32#include "llvm/ADT/APFixedPoint.h"
33#include "llvm/IR/CFG.h"
34#include "llvm/IR/Constants.h"
35#include "llvm/IR/DataLayout.h"
36#include "llvm/IR/DerivedTypes.h"
37#include "llvm/IR/FixedPointBuilder.h"
38#include "llvm/IR/Function.h"
39#include "llvm/IR/GEPNoWrapFlags.h"
40#include "llvm/IR/GetElementPtrTypeIterator.h"
41#include "llvm/IR/GlobalVariable.h"
42#include "llvm/IR/Intrinsics.h"
43#include "llvm/IR/IntrinsicsPowerPC.h"
44#include "llvm/IR/MatrixBuilder.h"
45#include "llvm/IR/Module.h"
46#include "llvm/Support/TypeSize.h"
51using namespace CodeGen;
69bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
71 llvm::APInt &Result) {
74 const auto &LHSAP = LHS->getValue();
75 const auto &RHSAP = RHS->getValue();
76 if (Opcode == BO_Add) {
77 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
78 : LHSAP.uadd_ov(RHSAP, Overflow);
79 }
else if (Opcode == BO_Sub) {
80 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
81 : LHSAP.usub_ov(RHSAP, Overflow);
82 }
else if (Opcode == BO_Mul) {
83 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
84 : LHSAP.umul_ov(RHSAP, Overflow);
85 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
86 if (
Signed && !RHS->isZero())
87 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
103 bool mayHaveIntegerOverflow()
const {
105 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
106 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
107 if (!LHSCI || !RHSCI)
111 return ::mayHaveIntegerOverflow(
116 bool isDivremOp()
const {
122 bool mayHaveIntegerDivisionByZero()
const {
124 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
130 bool mayHaveFloatDivisionByZero()
const {
132 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
133 return CFP->isZero();
140 bool isFixedPointOp()
const {
143 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
144 QualType LHSType = BinOp->getLHS()->getType();
145 QualType RHSType = BinOp->getRHS()->getType();
148 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
149 return UnOp->getSubExpr()->getType()->isFixedPointType();
154 bool rhsHasSignedIntegerRepresentation()
const {
155 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
156 QualType RHSType = BinOp->getRHS()->getType();
163static bool MustVisitNullValue(
const Expr *
E) {
171static std::optional<QualType> getUnwidenedIntegerType(
const ASTContext &Ctx,
187 return getUnwidenedIntegerType(Ctx,
E).has_value();
191static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
192 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
193 "Expected a unary or binary operator");
197 if (!Op.mayHaveIntegerOverflow())
200 if (Op.Ty->isSignedIntegerType() &&
206 if (Op.Ty->isUnsignedIntegerType() &&
216 LangOptions::OverflowPatternExclusionKind::NegUnsignedConst) &&
226 const auto *BO = cast<BinaryOperator>(Op.E);
227 if (BO->hasExcludedOverflowPattern())
230 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
234 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
243 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
249 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
250 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
254class ScalarExprEmitter
258 bool IgnoreResultAssign;
259 llvm::LLVMContext &VMContext;
263 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
264 VMContext(cgf.getLLVMContext()) {
271 bool TestAndClearIgnoreResultAssign() {
272 bool I = IgnoreResultAssign;
273 IgnoreResultAssign =
false;
279 LValue EmitCheckedLValue(
const Expr *
E, CodeGenFunction::TypeCheckKind TCK) {
283 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
284 const BinOpInfo &Info);
290 void EmitLValueAlignmentAssumption(
const Expr *
E,
Value *
V) {
291 const AlignValueAttr *AVAttr =
nullptr;
292 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E)) {
296 if (
const auto *TTy =
298 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
305 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
308 AVAttr = VD->
getAttr<AlignValueAttr>();
314 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
320 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
328 Value *
V = EmitLoadOfLValue(EmitCheckedLValue(
E, CodeGenFunction::TCK_Load),
331 EmitLValueAlignmentAssumption(
E,
V);
341 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
348 enum ImplicitConversionCheckKind :
unsigned char {
349 ICCK_IntegerTruncation = 0,
350 ICCK_UnsignedIntegerTruncation = 1,
351 ICCK_SignedIntegerTruncation = 2,
352 ICCK_IntegerSignChange = 3,
353 ICCK_SignedIntegerTruncationOrSignChange = 4,
369 struct ScalarConversionOpts {
370 bool TreatBooleanAsSigned;
371 bool EmitImplicitIntegerTruncationChecks;
372 bool EmitImplicitIntegerSignChangeChecks;
374 ScalarConversionOpts()
375 : TreatBooleanAsSigned(
false),
376 EmitImplicitIntegerTruncationChecks(
false),
377 EmitImplicitIntegerSignChangeChecks(
false) {}
380 : TreatBooleanAsSigned(
false),
381 EmitImplicitIntegerTruncationChecks(
383 EmitImplicitIntegerSignChangeChecks(
387 llvm::Type *SrcTy, llvm::Type *DstTy,
388 ScalarConversionOpts Opts);
392 ScalarConversionOpts Opts = ScalarConversionOpts());
401 Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
411 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
412 return Builder.CreateFCmpUNE(
V, Zero,
"tobool");
419 return Builder.CreateICmpNE(
V, Zero,
"tobool");
426 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
427 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
428 Value *Result = ZI->getOperand(0);
433 ZI->eraseFromParent();
438 return Builder.CreateIsNotNull(
V,
"tobool");
452 llvm_unreachable(
"Stmt can't have complex result type!");
470 return Visit(
E->getSubExpr());
476 return Visit(
E->getReplacement());
479 return Visit(
GE->getResultExpr());
488 return Visit(
E->getSubExpr());
493 return Builder.getInt(
E->getValue());
496 return Builder.getInt(
E->getValue());
499 return llvm::ConstantFP::get(VMContext,
E->getValue());
502 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
505 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
508 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
523 return Builder.CreateBitCast(
V, ConvertType(
E->
getType()));
527 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getPackLength());
547 llvm_unreachable(
"Codegen for this isn't defined/implemented");
554 return EmitLoadOfLValue(
E);
564 return EmitLoadOfLValue(
E);
567 if (
E->getMethodDecl() &&
568 E->getMethodDecl()->getReturnType()->isReferenceType())
569 return EmitLoadOfLValue(
E);
580 VersionTuple Version =
E->getVersion();
585 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
595 Value *VisitExtVectorElementExpr(
Expr *
E) {
return EmitLoadOfLValue(
E); }
602 return EmitLoadOfLValue(
E);
609 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
618 return VisitCastExpr(
E);
623 if (
E->getCallReturnType(CGF.
getContext())->isReferenceType())
624 return EmitLoadOfLValue(
E);
628 EmitLValueAlignmentAssumption(
E,
V);
636 LValue LV = EmitLValue(
E->getSubExpr());
637 return EmitScalarPrePostIncDec(
E, LV,
false,
false);
640 LValue LV = EmitLValue(
E->getSubExpr());
641 return EmitScalarPrePostIncDec(
E, LV,
true,
false);
644 LValue LV = EmitLValue(
E->getSubExpr());
645 return EmitScalarPrePostIncDec(
E, LV,
false,
true);
648 LValue LV = EmitLValue(
E->getSubExpr());
649 return EmitScalarPrePostIncDec(
E, LV,
true,
true);
652 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *
E,
657 bool isInc,
bool isPre);
661 if (isa<MemberPointerType>(
E->
getType()))
664 return EmitLValue(
E->getSubExpr()).getPointer(CGF);
668 return Visit(
E->getSubExpr());
669 return EmitLoadOfLValue(
E);
688 return Visit(
E->getSubExpr());
693 return EmitLoadOfLValue(
E);
704 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
708 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
725 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
729 return Builder.getInt1(
E->isSatisfied());
733 return Builder.getInt1(
E->isSatisfied());
737 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
741 return llvm::ConstantInt::get(Builder.getInt1Ty(),
E->getValue());
764 return Builder.getInt1(
E->getValue());
768 Value *EmitMul(
const BinOpInfo &Ops) {
769 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
770 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
772 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
773 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
776 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
777 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
780 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
781 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
782 return EmitOverflowCheckedBinOp(Ops);
786 if (Ops.Ty->isConstantMatrixType()) {
787 llvm::MatrixBuilder MB(Builder);
790 auto *BO = cast<BinaryOperator>(Ops.E);
791 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
792 BO->getLHS()->getType().getCanonicalType());
793 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
794 BO->getRHS()->getType().getCanonicalType());
795 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
796 if (LHSMatTy && RHSMatTy)
797 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
798 LHSMatTy->getNumColumns(),
799 RHSMatTy->getNumColumns());
800 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
803 if (Ops.Ty->isUnsignedIntegerType() &&
804 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
805 !CanElideOverflowCheck(CGF.
getContext(), Ops))
806 return EmitOverflowCheckedBinOp(Ops);
808 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
810 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
811 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
813 if (Ops.isFixedPointOp())
814 return EmitFixedPointBinOp(Ops);
815 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
819 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
822 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
823 llvm::Value *Zero,
bool isDiv);
825 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
831 Value *EmitDiv(
const BinOpInfo &Ops);
832 Value *EmitRem(
const BinOpInfo &Ops);
833 Value *EmitAdd(
const BinOpInfo &Ops);
834 Value *EmitSub(
const BinOpInfo &Ops);
835 Value *EmitShl(
const BinOpInfo &Ops);
836 Value *EmitShr(
const BinOpInfo &Ops);
837 Value *EmitAnd(
const BinOpInfo &Ops) {
838 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
840 Value *EmitXor(
const BinOpInfo &Ops) {
841 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
843 Value *EmitOr (
const BinOpInfo &Ops) {
844 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
848 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
858 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
862 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
867 QualType ElementType = CT->getElementType();
874 unsigned NumElements = VT->getNumElements();
884#define HANDLEBINOP(OP) \
885 Value *VisitBin##OP(const BinaryOperator *E) { \
886 QualType promotionTy = getPromotionType(E->getType()); \
887 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
888 if (result && !promotionTy.isNull()) \
889 result = EmitUnPromotedValue(result, E->getType()); \
892 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
893 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
909 llvm::CmpInst::Predicate SICmpOpc,
910 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
911#define VISITCOMP(CODE, UI, SI, FP, SIG) \
912 Value *VisitBin##CODE(const BinaryOperator *E) { \
913 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
914 llvm::FCmpInst::FP, SIG); }
929 Value *VisitBinPtrMemD(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
930 Value *VisitBinPtrMemI(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
933 return Visit(
E->getSemanticForm());
956 return Visit(
E->getSelectedExpr());
968 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
971 return EmitFloatToBoolConversion(Src);
977 "Unknown scalar type to convert");
979 if (isa<llvm::IntegerType>(Src->
getType()))
980 return EmitIntToBoolConversion(Src);
982 assert(isa<llvm::PointerType>(Src->
getType()));
983 return EmitPointerToBoolConversion(Src, SrcType);
986void ScalarExprEmitter::EmitFloatConversionCheck(
989 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
990 if (!isa<llvm::IntegerType>(DstTy))
993 CodeGenFunction::SanitizerScope SanScope(&CGF);
997 llvm::Value *Check =
nullptr;
998 const llvm::fltSemantics &SrcSema =
1008 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1009 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1010 APFloat::opOverflow)
1013 MinSrc = APFloat::getInf(SrcSema,
true);
1017 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1020 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1021 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1022 APFloat::opOverflow)
1025 MaxSrc = APFloat::getInf(SrcSema,
false);
1029 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1034 const llvm::fltSemantics &
Sema =
1037 MinSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1038 MaxSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1042 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1044 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1045 Check = Builder.CreateAnd(GE, LE);
1050 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
1051 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
1056static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1057 std::pair<llvm::Value *, SanitizerMask>>
1060 llvm::Type *SrcTy = Src->
getType();
1061 llvm::Type *DstTy = Dst->
getType();
1066 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1067 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1068 "non-integer llvm type");
1075 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1077 if (!SrcSigned && !DstSigned) {
1078 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1079 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
1081 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1082 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
1085 llvm::Value *Check =
nullptr;
1087 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1089 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1091 return std::make_pair(Kind, std::make_pair(Check, Mask));
1099void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1111 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1112 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1114 if (SrcBits <= DstBits)
1117 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1124 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1125 (!SrcSigned && DstSigned))
1128 CodeGenFunction::SanitizerScope SanScope(&CGF);
1130 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1131 std::pair<llvm::Value *, SanitizerMask>>
1144 llvm::Constant *StaticArgs[] = {
1147 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1148 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1150 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1158 llvm::Type *VTy =
V->getType();
1161 return llvm::ConstantInt::getFalse(VTy->getContext());
1163 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1164 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V, Zero,
1165 llvm::Twine(Name) +
"." +
V->getName() +
1166 ".negativitycheck");
1171static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1172 std::pair<llvm::Value *, SanitizerMask>>
1175 llvm::Type *SrcTy = Src->
getType();
1176 llvm::Type *DstTy = Dst->
getType();
1178 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1179 "non-integer llvm type");
1185 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1186 unsigned DstBits = DstTy->getScalarSizeInBits();
1190 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1191 "either the widths should be different, or the signednesses.");
1194 llvm::Value *SrcIsNegative =
1197 llvm::Value *DstIsNegative =
1203 llvm::Value *Check =
nullptr;
1204 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1206 return std::make_pair(
1207 ScalarExprEmitter::ICCK_IntegerSignChange,
1208 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1211void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1214 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1217 llvm::Type *SrcTy = Src->
getType();
1218 llvm::Type *DstTy = Dst->
getType();
1228 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1229 unsigned DstBits = DstTy->getScalarSizeInBits();
1236 if (SrcSigned == DstSigned && SrcBits == DstBits)
1240 if (!SrcSigned && !DstSigned)
1245 if ((DstBits > SrcBits) && DstSigned)
1247 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1248 (SrcBits > DstBits) && SrcSigned) {
1257 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1261 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1265 CodeGenFunction::SanitizerScope SanScope(&CGF);
1267 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1268 std::pair<llvm::Value *, SanitizerMask>>
1272 ImplicitConversionCheckKind CheckKind;
1278 CheckKind = Check.first;
1279 Checks.emplace_back(Check.second);
1281 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1282 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1288 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1289 Checks.emplace_back(Check.second);
1293 llvm::Constant *StaticArgs[] = {
1296 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1297 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1299 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1305static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1306 std::pair<llvm::Value *, SanitizerMask>>
1312 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1313 if (!SrcSigned && !DstSigned)
1314 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1316 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1318 llvm::Value *Check =
nullptr;
1320 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1322 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1325 return std::make_pair(
1326 Kind, std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1331static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1332 std::pair<llvm::Value *, SanitizerMask>>
1336 llvm::Value *SrcIsNegative =
1339 llvm::Value *DstIsNegative =
1345 llvm::Value *Check =
nullptr;
1347 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1349 return std::make_pair(
1350 ScalarExprEmitter::ICCK_IntegerSignChange,
1351 std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1354void CodeGenFunction::EmitBitfieldConversionCheck(
Value *Src,
QualType SrcType,
1359 if (!
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion))
1372 assert(isa<llvm::IntegerType>(Src->
getType()) &&
1373 isa<llvm::IntegerType>(Dst->
getType()) &&
"non-integer llvm type");
1377 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1378 unsigned DstBits = Info.
Size;
1383 CodeGenFunction::SanitizerScope SanScope(
this);
1385 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1386 std::pair<llvm::Value *, SanitizerMask>>
1390 bool EmitTruncation = DstBits < SrcBits;
1394 bool EmitTruncationFromUnsignedToSigned =
1395 EmitTruncation && DstSigned && !SrcSigned;
1397 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1398 bool BothUnsigned = !SrcSigned && !DstSigned;
1399 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1406 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1411 else if (EmitSignChange) {
1412 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1413 "either the widths should be different, or the signednesses.");
1419 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1420 if (EmitTruncationFromUnsignedToSigned)
1421 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1423 llvm::Constant *StaticArgs[] = {
1426 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1427 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1429 EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1434 QualType DstType, llvm::Type *SrcTy,
1436 ScalarConversionOpts Opts) {
1438 llvm::Type *SrcElementTy;
1439 llvm::Type *DstElementTy;
1443 SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1444 DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1449 "cannot cast between matrix and non-matrix types");
1450 SrcElementTy = SrcTy;
1451 DstElementTy = DstTy;
1452 SrcElementType = SrcType;
1453 DstElementType = DstType;
1456 if (isa<llvm::IntegerType>(SrcElementTy)) {
1458 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1462 if (isa<llvm::IntegerType>(DstElementTy))
1463 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1465 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1466 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1469 if (isa<llvm::IntegerType>(DstElementTy)) {
1470 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1477 llvm::Intrinsic::ID IID =
1478 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1479 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1483 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1484 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1487 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1488 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1489 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1491 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1492 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1493 return Builder.CreateFPExt(Src, DstTy,
"conv");
1501 ScalarConversionOpts Opts) {
1516 return Builder.CreateIsNotNull(Src,
"tobool");
1519 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1522 "Unhandled scalar conversion from a fixed point type to another type.");
1526 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1529 "Unhandled scalar conversion to a fixed point type from another type.");
1532 QualType NoncanonicalSrcType = SrcType;
1533 QualType NoncanonicalDstType = DstType;
1537 if (SrcType == DstType)
return Src;
1541 llvm::Value *OrigSrc = Src;
1543 llvm::Type *SrcTy = Src->
getType();
1547 return EmitConversionToBool(Src, SrcType);
1549 llvm::Type *DstTy = ConvertType(DstType);
1554 if (DstTy->isFloatingPointTy()) {
1556 return Builder.CreateCall(
1564 Src = Builder.CreateCall(
1569 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1577 if (SrcTy == DstTy) {
1578 if (Opts.EmitImplicitIntegerSignChangeChecks)
1579 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1580 NoncanonicalDstType,
Loc);
1588 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1590 if (isa<llvm::PointerType>(SrcTy))
1593 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1598 llvm::Value* IntResult =
1599 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1601 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1604 if (isa<llvm::PointerType>(SrcTy)) {
1606 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1607 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1616 "Splatted expr doesn't match with vector element type?");
1619 unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
1620 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1624 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1626 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1628 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1629 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1630 if (SrcSize == DstSize)
1631 return Builder.CreateBitCast(Src, DstTy,
"conv");
1640 llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1641 llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1644 assert(((SrcElementTy->isIntegerTy() &&
1645 DstElementTy->isIntegerTy()) ||
1646 (SrcElementTy->isFloatingPointTy() &&
1647 DstElementTy->isFloatingPointTy())) &&
1648 "unexpected conversion between a floating-point vector and an "
1652 if (SrcElementTy->isIntegerTy())
1653 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1656 if (SrcSize > DstSize)
1657 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1660 return Builder.CreateFPExt(Src, DstTy,
"conv");
1664 Value *Res =
nullptr;
1665 llvm::Type *ResTy = DstTy;
1672 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1674 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1680 if (SrcTy->isFloatingPointTy()) {
1684 return Builder.CreateCall(
1687 return Builder.CreateFPTrunc(Src, DstTy);
1692 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1694 if (DstTy != ResTy) {
1696 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1697 Res = Builder.CreateCall(
1701 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1705 if (Opts.EmitImplicitIntegerTruncationChecks)
1706 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1707 NoncanonicalDstType,
Loc);
1709 if (Opts.EmitImplicitIntegerSignChangeChecks)
1710 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1711 NoncanonicalDstType,
Loc);
1719 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1722 Result = FPBuilder.CreateFloatingToFixed(Src,
1725 Result = FPBuilder.CreateFixedToFloating(Src,
1727 ConvertType(DstTy));
1733 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1734 DstFPSema.getWidth(),
1735 DstFPSema.isSigned());
1737 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1740 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1747Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1756 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1757 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy,
Loc);
1758 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1765 return EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1776void ScalarExprEmitter::EmitBinOpCheck(
1777 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1789 if (UO && UO->
getOpcode() == UO_Minus) {
1790 Check = SanitizerHandler::NegateOverflow;
1792 DynamicData.push_back(Info.RHS);
1796 Check = SanitizerHandler::ShiftOutOfBounds;
1798 StaticData.push_back(
1800 StaticData.push_back(
1802 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1804 Check = SanitizerHandler::DivremOverflow;
1809 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1810 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1811 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1812 default: llvm_unreachable(
"unexpected opcode for bin op check");
1816 DynamicData.push_back(Info.LHS);
1817 DynamicData.push_back(Info.RHS);
1820 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1827Value *ScalarExprEmitter::VisitExpr(
Expr *
E) {
1837 unsigned AddrSpace =
1839 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1840 E->ComputeName(Context),
"__usn_str", AddrSpace);
1842 llvm::Type *ExprTy = ConvertType(
E->
getType());
1843 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1848 assert(
E->getDataElementCount() == 1);
1849 auto It =
E->begin();
1850 return Builder.getInt((*It)->getValue());
1855 if (
E->getNumSubExprs() == 2) {
1860 auto *LTy = cast<llvm::FixedVectorType>(LHS->
getType());
1861 unsigned LHSElts = LTy->getNumElements();
1865 auto *MTy = cast<llvm::FixedVectorType>(Mask->
getType());
1869 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1870 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1878 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1879 MTy->getNumElements());
1880 Value* NewV = llvm::PoisonValue::get(RTy);
1881 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1882 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1883 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1885 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1886 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1895 for (
unsigned i = 2; i <
E->getNumSubExprs(); ++i) {
1896 llvm::APSInt Idx =
E->getShuffleMaskIdx(CGF.
getContext(), i-2);
1898 if (Idx.isSigned() && Idx.isAllOnes())
1899 Indices.push_back(-1);
1901 Indices.push_back(Idx.getZExtValue());
1904 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1915 if (SrcType == DstType)
return Src;
1918 "ConvertVector source type must be a vector");
1920 "ConvertVector destination type must be a vector");
1922 llvm::Type *SrcTy = Src->
getType();
1923 llvm::Type *DstTy = ConvertType(DstType);
1932 assert(SrcTy->isVectorTy() &&
1933 "ConvertVector source IR type must be a vector");
1934 assert(DstTy->isVectorTy() &&
1935 "ConvertVector destination IR type must be a vector");
1937 llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
1938 *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
1940 if (DstEltType->isBooleanType()) {
1941 assert((SrcEltTy->isFloatingPointTy() ||
1942 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1944 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
1945 if (SrcEltTy->isFloatingPointTy()) {
1946 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1948 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1953 Value *Res =
nullptr;
1955 if (isa<llvm::IntegerType>(SrcEltTy)) {
1957 if (isa<llvm::IntegerType>(DstEltTy))
1958 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1959 else if (InputSigned)
1960 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1962 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1963 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1964 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1965 if (DstEltType->isSignedIntegerOrEnumerationType())
1966 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1968 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1970 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1971 "Unknown real conversion");
1972 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1973 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1975 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1990 return Builder.getInt(
Value);
1994 llvm::Value *
Result = EmitLoadOfLValue(
E);
2000 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2001 if (llvm::GetElementPtrInst *GEP =
2002 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2003 if (llvm::Instruction *
Pointer =
2004 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2017 TestAndClearIgnoreResultAssign();
2025 return EmitLoadOfLValue(
E);
2030 Value *Idx = Visit(
E->getIdx());
2033 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2036 return Builder.CreateExtractElement(
Base, Idx,
"vecext");
2040 TestAndClearIgnoreResultAssign();
2049 llvm::MatrixBuilder MB(Builder);
2050 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2052 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2054 Value *Matrix = Visit(
E->getBase());
2057 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2062 int MV = SVI->getMaskValue(Idx);
2069 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2070 "Index operand too large for shufflevector mask!");
2071 return C->getZExtValue();
2075 bool Ignore = TestAndClearIgnoreResultAssign();
2077 assert (Ignore ==
false &&
"init list ignored");
2078 unsigned NumInitElements =
E->getNumInits();
2080 if (
E->hadArrayRangeDesignator())
2083 llvm::VectorType *VType =
2084 dyn_cast<llvm::VectorType>(ConvertType(
E->
getType()));
2087 if (NumInitElements == 0) {
2089 return EmitNullValue(
E->
getType());
2092 return Visit(
E->getInit(0));
2095 if (isa<llvm::ScalableVectorType>(VType)) {
2096 if (NumInitElements == 0) {
2098 return EmitNullValue(
E->
getType());
2101 if (NumInitElements == 1) {
2102 Expr *InitVector =
E->getInit(0);
2107 return Visit(InitVector);
2110 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2113 unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
2120 unsigned CurIdx = 0;
2121 bool VIsPoisonShuffle =
false;
2122 llvm::Value *
V = llvm::PoisonValue::get(VType);
2123 for (
unsigned i = 0; i != NumInitElements; ++i) {
2124 Expr *IE =
E->getInit(i);
2128 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2134 if (isa<ExtVectorElementExpr>(IE)) {
2135 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(
Init);
2137 if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
2138 ->getNumElements() == ResElts) {
2139 llvm::ConstantInt *
C = cast<llvm::ConstantInt>(EI->getIndexOperand());
2140 Value *LHS =
nullptr, *RHS =
nullptr;
2145 Args.resize(ResElts, -1);
2147 LHS = EI->getVectorOperand();
2149 VIsPoisonShuffle =
true;
2150 }
else if (VIsPoisonShuffle) {
2152 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
2153 for (
unsigned j = 0; j != CurIdx; ++j)
2155 Args.push_back(ResElts +
C->getZExtValue());
2156 Args.resize(ResElts, -1);
2158 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2159 RHS = EI->getVectorOperand();
2160 VIsPoisonShuffle =
false;
2162 if (!Args.empty()) {
2163 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2169 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2171 VIsPoisonShuffle =
false;
2176 unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
2181 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2182 if (isa<ExtVectorElementExpr>(IE)) {
2183 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(
Init);
2184 Value *SVOp = SVI->getOperand(0);
2185 auto *OpTy = cast<llvm::FixedVectorType>(SVOp->
getType());
2187 if (OpTy->getNumElements() == ResElts) {
2188 for (
unsigned j = 0; j != CurIdx; ++j) {
2191 if (VIsPoisonShuffle) {
2192 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(
V), j, 0));
2197 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2199 Args.resize(ResElts, -1);
2201 if (VIsPoisonShuffle)
2202 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2211 for (
unsigned j = 0; j != InitElts; ++j)
2213 Args.resize(ResElts, -1);
2214 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2217 for (
unsigned j = 0; j != CurIdx; ++j)
2219 for (
unsigned j = 0; j != InitElts; ++j)
2220 Args.push_back(j + Offset);
2221 Args.resize(ResElts, -1);
2228 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2229 VIsPoisonShuffle = isa<llvm::PoisonValue>(
Init);
2235 llvm::Type *EltTy = VType->getElementType();
2238 for (; CurIdx < ResElts; ++CurIdx) {
2239 Value *Idx = Builder.getInt32(CurIdx);
2240 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2241 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2249 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2259 if (ICE->isGLValue())
2273 CodeGenFunction::CGFPOptionsRAII
FPOptions(CGF, CE);
2277 bool Ignored = TestAndClearIgnoreResultAssign();
2283 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2284 case CK_BuiltinFnToFnPtr:
2285 llvm_unreachable(
"builtin functions are handled elsewhere");
2287 case CK_LValueBitCast:
2288 case CK_ObjCObjectLValueCast: {
2289 Address Addr = EmitLValue(
E).getAddress();
2292 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2295 case CK_LValueToRValueBitCast: {
2301 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2304 case CK_CPointerToObjCPointerCast:
2305 case CK_BlockPointerToObjCPointerCast:
2306 case CK_AnyPointerToBlockPointerCast:
2309 llvm::Type *SrcTy = Src->
getType();
2310 llvm::Type *DstTy = ConvertType(DestTy);
2312 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2313 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2314 "Address-space cast must be used to convert address spaces");
2316 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2319 PT->getPointeeType(),
2335 Src = Builder.CreateLaunderInvariantGroup(Src);
2343 Src = Builder.CreateStripInvariantGroup(Src);
2348 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2349 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE) &&
2350 !isa<CastExpr>(
E)) {
2352 if (!PointeeType.
isNull())
2361 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2362 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2365 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2366 ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
2367 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2368 ScalableDstTy = llvm::ScalableVectorType::get(
2369 FixedSrcTy->getElementType(),
2370 ScalableDstTy->getElementCount().getKnownMinValue() / 8);
2372 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2373 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2374 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2375 llvm::Value *
Result = Builder.CreateInsertVector(
2376 ScalableDstTy, PoisonVec, Src, Zero,
"cast.scalable");
2377 if (
Result->getType() != DstTy)
2387 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2388 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2391 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2392 ScalableSrcTy->getElementCount().isKnownMultipleOf(8) &&
2393 FixedDstTy->getElementType()->isIntegerTy(8)) {
2394 ScalableSrcTy = llvm::ScalableVectorType::get(
2395 FixedDstTy->getElementType(),
2396 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2397 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2399 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType()) {
2400 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2401 return Builder.CreateExtractVector(DstTy, Src, Zero,
"cast.fixed");
2412 if ((isa<llvm::FixedVectorType>(SrcTy) &&
2413 isa<llvm::ScalableVectorType>(DstTy)) ||
2414 (isa<llvm::ScalableVectorType>(SrcTy) &&
2415 isa<llvm::FixedVectorType>(DstTy))) {
2422 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2425 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2428 case CK_AddressSpaceConversion: {
2431 Result.Val.isNullPointer()) {
2435 if (
Result.HasSideEffects)
2438 ConvertType(DestTy)), DestTy);
2446 case CK_AtomicToNonAtomic:
2447 case CK_NonAtomicToAtomic:
2448 case CK_UserDefinedConversion:
2449 return Visit(
const_cast<Expr*
>(
E));
2453 : Visit(const_cast<
Expr *>(
E));
2456 case CK_BaseToDerived: {
2458 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2472 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2480 case CK_UncheckedDerivedToBase:
2481 case CK_DerivedToBase: {
2494 case CK_ArrayToPointerDecay:
2497 case CK_FunctionToPointerDecay:
2498 return EmitLValue(
E).getPointer(CGF);
2500 case CK_NullToPointer:
2501 if (MustVisitNullValue(
E))
2507 case CK_NullToMemberPointer: {
2508 if (MustVisitNullValue(
E))
2515 case CK_ReinterpretMemberPointer:
2516 case CK_BaseToDerivedMemberPointer:
2517 case CK_DerivedToBaseMemberPointer: {
2529 case CK_ARCProduceObject:
2531 case CK_ARCConsumeObject:
2533 case CK_ARCReclaimReturnedObject:
2535 case CK_ARCExtendBlockObject:
2538 case CK_CopyAndAutoreleaseBlockObject:
2541 case CK_FloatingRealToComplex:
2542 case CK_FloatingComplexCast:
2543 case CK_IntegralRealToComplex:
2544 case CK_IntegralComplexCast:
2545 case CK_IntegralComplexToFloatingComplex:
2546 case CK_FloatingComplexToIntegralComplex:
2547 case CK_ConstructorConversion:
2549 case CK_HLSLArrayRValue:
2550 llvm_unreachable(
"scalar cast to non-scalar value");
2552 case CK_LValueToRValue:
2554 assert(
E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2555 return Visit(
const_cast<Expr*
>(
E));
2557 case CK_IntegralToPointer: {
2562 auto DestLLVMTy = ConvertType(DestTy);
2565 llvm::Value* IntResult =
2566 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2568 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2574 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2580 case CK_PointerToIntegral: {
2581 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2582 auto *PtrExpr = Visit(
E);
2590 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2594 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2600 case CK_MatrixCast: {
2601 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2604 case CK_VectorSplat: {
2605 llvm::Type *DstTy = ConvertType(DestTy);
2608 llvm::ElementCount NumElements =
2609 cast<llvm::VectorType>(DstTy)->getElementCount();
2610 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2613 case CK_FixedPointCast:
2614 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2617 case CK_FixedPointToBoolean:
2619 "Expected src type to be fixed point type");
2620 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2621 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2624 case CK_FixedPointToIntegral:
2626 "Expected src type to be fixed point type");
2627 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2628 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2631 case CK_IntegralToFixedPoint:
2633 "Expected src type to be an integer");
2635 "Expected dest type to be fixed point type");
2636 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2639 case CK_IntegralCast: {
2642 return Builder.CreateIntCast(Visit(
E), ConvertType(DestTy),
2646 ScalarConversionOpts Opts;
2647 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2648 if (!ICE->isPartOfExplicitCast())
2649 Opts = ScalarConversionOpts(CGF.
SanOpts);
2651 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2654 case CK_IntegralToFloating: {
2659 return Builder.CreateSIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2660 return Builder.CreateUIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2662 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2663 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2666 case CK_FloatingToIntegral: {
2671 return Builder.CreateFPToSI(Visit(
E), ConvertType(DestTy),
"conv");
2672 return Builder.CreateFPToUI(Visit(
E), ConvertType(DestTy),
"conv");
2674 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2675 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2678 case CK_FloatingCast: {
2685 return Builder.CreateFPTrunc(Visit(
E), ConvertType(DestTy),
"conv");
2686 return Builder.CreateFPExt(Visit(
E), ConvertType(DestTy),
"conv");
2688 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2689 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2692 case CK_FixedPointToFloating:
2693 case CK_FloatingToFixedPoint: {
2694 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2695 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2698 case CK_BooleanToSignedIntegral: {
2699 ScalarConversionOpts Opts;
2700 Opts.TreatBooleanAsSigned =
true;
2701 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2704 case CK_IntegralToBoolean:
2705 return EmitIntToBoolConversion(Visit(
E));
2706 case CK_PointerToBoolean:
2707 return EmitPointerToBoolConversion(Visit(
E),
E->
getType());
2708 case CK_FloatingToBoolean: {
2709 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2710 return EmitFloatToBoolConversion(Visit(
E));
2712 case CK_MemberPointerToBoolean: {
2713 llvm::Value *MemPtr = Visit(
E);
2718 case CK_FloatingComplexToReal:
2719 case CK_IntegralComplexToReal:
2722 case CK_FloatingComplexToBoolean:
2723 case CK_IntegralComplexToBoolean: {
2727 return EmitComplexToScalarConversion(
V,
E->
getType(), DestTy,
2731 case CK_ZeroToOCLOpaqueType: {
2734 "CK_ZeroToOCLEvent cast on non-event type");
2735 return llvm::Constant::getNullValue(ConvertType(DestTy));
2738 case CK_IntToOCLSampler:
2741 case CK_HLSLVectorTruncation: {
2743 "Destination type must be a vector or builtin type.");
2747 unsigned NumElts = VecTy->getNumElements();
2748 for (
unsigned I = 0; I != NumElts; ++I)
2751 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2753 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
2754 return Builder.CreateExtractElement(Vec, Zero,
"cast.vtrunc");
2759 llvm_unreachable(
"unknown scalar cast");
2763 CodeGenFunction::StmtExprEvaluation eval(CGF);
2773 CodeGenFunction::RunCleanupsScope
Scope(CGF);
2774 Value *
V = Visit(
E->getSubExpr());
2777 Scope.ForceCleanup({&
V});
2786 llvm::Value *InVal,
bool IsInc,
2790 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2792 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2793 BinOp.FPFeatures = FPFeatures;
2798llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2800 llvm::Value *Amount =
2801 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2802 StringRef Name = IsInc ?
"inc" :
"dec";
2803 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2805 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2806 return Builder.CreateAdd(InVal, Amount, Name);
2809 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2810 return Builder.CreateNSWAdd(InVal, Amount, Name);
2815 if (!
E->canOverflow() || CanElideOverflowCheck(CGF.
getContext(), Info))
2816 return Builder.CreateNSWAdd(InVal, Amount, Name);
2817 return EmitOverflowCheckedBinOp(Info);
2819 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2844class OMPLastprivateConditionalUpdateRAII {
2853 ~OMPLastprivateConditionalUpdateRAII() {
2856 CGF,
E->getSubExpr());
2863 bool isInc,
bool isPre) {
2864 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF,
E);
2866 llvm::PHINode *atomicPHI =
nullptr;
2872 int amount = (isInc ? 1 : -1);
2873 bool isSubtraction = !isInc;
2876 type = atomicTy->getValueType();
2877 if (isInc &&
type->isBooleanType()) {
2881 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2882 return Builder.getTrue();
2886 return Builder.CreateAtomicRMW(
2888 llvm::AtomicOrdering::SequentiallyConsistent);
2893 if (!
type->isBooleanType() &&
type->isIntegerType() &&
2894 !(
type->isUnsignedIntegerType() &&
2895 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2898 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2899 llvm::AtomicRMWInst::Sub;
2900 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2901 llvm::Instruction::Sub;
2903 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
2905 Builder.CreateAtomicRMW(aop, LV.
getAddress(), amt,
2906 llvm::AtomicOrdering::SequentiallyConsistent);
2907 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2911 if (
type->isFloatingType()) {
2912 llvm::Type *Ty = ConvertType(
type);
2913 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
2914 llvm::AtomicRMWInst::BinOp aop =
2915 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
2916 llvm::Instruction::BinaryOps op =
2917 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
2918 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
2919 llvm::AtomicRMWInst *old =
2921 llvm::AtomicOrdering::SequentiallyConsistent);
2923 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2929 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2932 Builder.CreateBr(opBB);
2933 Builder.SetInsertPoint(opBB);
2934 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2935 atomicPHI->addIncoming(value, startBB);
2949 if (isInc &&
type->isBooleanType()) {
2950 value = Builder.getTrue();
2953 }
else if (
type->isIntegerType()) {
2955 bool canPerformLossyDemotionCheck =
false;
2957 bool excludeOverflowPattern =
2962 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
2963 canPerformLossyDemotionCheck =
true;
2964 canPerformLossyDemotionCheck &=
2967 canPerformLossyDemotionCheck &=
2969 type, promotedType);
2970 assert((!canPerformLossyDemotionCheck ||
2971 type->isSignedIntegerOrEnumerationType() ||
2973 ConvertType(
type)->getScalarSizeInBits() ==
2974 ConvertType(promotedType)->getScalarSizeInBits()) &&
2975 "The following check expects that if we do promotion to different "
2976 "underlying canonical type, at least one of the types (either "
2977 "base or promoted) will be signed, or the bitwidths will match.");
2980 SanitizerKind::ImplicitIntegerArithmeticValueChange |
2981 SanitizerKind::ImplicitBitfieldConversion) &&
2982 canPerformLossyDemotionCheck) {
2996 value = EmitScalarConversion(value,
type, promotedType,
E->
getExprLoc());
2997 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2998 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3002 ScalarConversionOpts Opts;
3004 Opts = ScalarConversionOpts(CGF.
SanOpts);
3005 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3007 SrcType = promotedType;
3010 value = EmitScalarConversion(value, promotedType,
type,
E->
getExprLoc(),
3016 }
else if (
E->canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
3017 value = EmitIncDecConsiderOverflowBehavior(
E, value, isInc);
3018 }
else if (
E->canOverflow() &&
type->isUnsignedIntegerType() &&
3019 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3020 !excludeOverflowPattern &&
3022 SanitizerKind::UnsignedIntegerOverflow,
E->
getType())) {
3026 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3027 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3038 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3041 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3044 elemTy, value, numElts,
false, isSubtraction,
3048 }
else if (
type->isFunctionType()) {
3049 llvm::Value *amt = Builder.getInt32(amount);
3052 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3056 false, isSubtraction,
3061 llvm::Value *amt = Builder.getInt32(amount);
3064 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3067 elemTy, value, amt,
false, isSubtraction,
3072 }
else if (
type->isVectorType()) {
3073 if (
type->hasIntegerRepresentation()) {
3074 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
3076 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3078 value = Builder.CreateFAdd(
3080 llvm::ConstantFP::get(value->getType(), amount),
3081 isInc ?
"inc" :
"dec");
3085 }
else if (
type->isRealFloatingType()) {
3088 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF,
E);
3093 value = Builder.CreateCall(
3096 input,
"incdec.conv");
3098 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3102 if (value->getType()->isFloatTy())
3103 amt = llvm::ConstantFP::get(VMContext,
3104 llvm::APFloat(
static_cast<float>(amount)));
3105 else if (value->getType()->isDoubleTy())
3106 amt = llvm::ConstantFP::get(VMContext,
3107 llvm::APFloat(
static_cast<double>(amount)));
3111 llvm::APFloat F(
static_cast<float>(amount));
3113 const llvm::fltSemantics *FS;
3116 if (value->getType()->isFP128Ty())
3118 else if (value->getType()->isHalfTy())
3120 else if (value->getType()->isBFloatTy())
3122 else if (value->getType()->isPPC_FP128Ty())
3126 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3127 amt = llvm::ConstantFP::get(VMContext, F);
3129 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3133 value = Builder.CreateCall(
3136 value,
"incdec.conv");
3138 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3143 }
else if (
type->isFixedPointType()) {
3150 Info.Opcode = isInc ? BO_Add : BO_Sub;
3152 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3155 if (
type->isSignedFixedPointType()) {
3156 Info.Opcode = isInc ? BO_Sub : BO_Add;
3157 Info.RHS = Builder.CreateNeg(Info.RHS);
3162 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3164 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3165 value = EmitFixedPointBinOp(Info);
3172 if (!isInc) size = -size;
3173 llvm::Value *sizeValue =
3174 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3177 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3180 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3182 value = Builder.CreateBitCast(value, input->getType());
3186 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3191 llvm::Value *
success = Pair.second;
3192 atomicPHI->addIncoming(old, curBlock);
3193 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3194 Builder.SetInsertPoint(contBB);
3195 return isPre ? value : input;
3209 return isPre ? value : input;
3216 ? getPromotionType(
E->getSubExpr()->
getType())
3218 Value *result = VisitPlus(
E, promotionTy);
3219 if (result && !promotionTy.
isNull())
3220 result = EmitUnPromotedValue(result,
E->
getType());
3227 TestAndClearIgnoreResultAssign();
3228 if (!PromotionType.
isNull())
3230 return Visit(
E->getSubExpr());
3236 ? getPromotionType(
E->getSubExpr()->
getType())
3238 Value *result = VisitMinus(
E, promotionTy);
3239 if (result && !promotionTy.
isNull())
3240 result = EmitUnPromotedValue(result,
E->
getType());
3246 TestAndClearIgnoreResultAssign();
3248 if (!PromotionType.
isNull())
3251 Op = Visit(
E->getSubExpr());
3254 if (Op->
getType()->isFPOrFPVectorTy())
3255 return Builder.CreateFNeg(Op,
"fneg");
3260 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3262 BinOp.Opcode = BO_Sub;
3265 return EmitSub(BinOp);
3269 TestAndClearIgnoreResultAssign();
3270 Value *Op = Visit(
E->getSubExpr());
3271 return Builder.CreateNot(Op,
"not");
3279 Value *Oper = Visit(
E->getSubExpr());
3282 if (Oper->
getType()->isFPOrFPVectorTy()) {
3283 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3285 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
3287 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
3288 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
3297 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3300 return Builder.CreateZExt(BoolVal, ConvertType(
E->
getType()),
"lnot.ext");
3308 return Builder.getInt(
Value);
3312 unsigned n =
E->getNumComponents();
3313 llvm::Type* ResultType = ConvertType(
E->
getType());
3314 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3316 for (
unsigned i = 0; i != n; ++i) {
3318 llvm::Value *Offset =
nullptr;
3325 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3332 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3336 Offset = Builder.CreateMul(Idx, ElemSize);
3350 Field != FieldEnd; ++Field, ++i) {
3351 if (*Field == MemberDecl)
3354 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3359 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3362 CurrentType = MemberDecl->
getType();
3367 llvm_unreachable(
"dependent __builtin_offsetof");
3383 auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
3385 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3397ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3399 QualType TypeToSize =
E->getTypeOfArgument();
3400 if (
auto Kind =
E->getKind();
3401 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
3404 if (
E->isArgumentType()) {
3414 llvm::Value *size = VlaSize.
NumElts;
3418 if (!eltSize.
isOne())
3423 }
else if (
E->getKind() == UETT_OpenMPRequiredSimdAlign) {
3427 E->getTypeOfArgument()->getPointeeType()))
3429 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3430 }
else if (
E->getKind() == UETT_VectorElements) {
3431 auto *VecTy = cast<llvm::VectorType>(ConvertType(
E->getTypeOfArgument()));
3432 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3443 ? getPromotionType(
E->getSubExpr()->
getType())
3445 Value *result = VisitReal(
E, promotionTy);
3446 if (result && !promotionTy.
isNull())
3447 result = EmitUnPromotedValue(result,
E->
getType());
3453 Expr *Op =
E->getSubExpr();
3459 if (!PromotionType.
isNull()) {
3461 Op, IgnoreResultAssign,
true);
3464 return result.first;
3474 if (!PromotionType.
isNull())
3482 ? getPromotionType(
E->getSubExpr()->
getType())
3484 Value *result = VisitImag(
E, promotionTy);
3485 if (result && !promotionTy.
isNull())
3486 result = EmitUnPromotedValue(result,
E->
getType());
3492 Expr *Op =
E->getSubExpr();
3498 if (!PromotionType.
isNull()) {
3500 Op,
true, IgnoreResultAssign);
3503 return result.second;
3517 else if (!PromotionType.
isNull())
3521 if (!PromotionType.
isNull())
3522 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3523 return llvm::Constant::getNullValue(ConvertType(
E->
getType()));
3530Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3532 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3535Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3537 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3542 if (
auto BO = dyn_cast<BinaryOperator>(
E)) {
3544#define HANDLE_BINOP(OP) \
3546 return Emit##OP(EmitBinOps(BO, PromotionType));
3555 }
else if (
auto UO = dyn_cast<UnaryOperator>(
E)) {
3558 return VisitImag(UO, PromotionType);
3560 return VisitReal(UO, PromotionType);
3562 return VisitMinus(UO, PromotionType);
3564 return VisitPlus(UO, PromotionType);
3569 auto result = Visit(
const_cast<Expr *
>(
E));
3571 if (!PromotionType.
isNull())
3572 return EmitPromotedValue(result, PromotionType);
3574 return EmitUnPromotedValue(result,
E->
getType());
3581 TestAndClearIgnoreResultAssign();
3585 if (!PromotionType.
isNull())
3586 Result.Ty = PromotionType;
3589 Result.Opcode =
E->getOpcode();
3595LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3597 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3602 if (
E->getComputationResultType()->isAnyComplexType())
3609 PromotionTypeCR = getPromotionType(
E->getComputationResultType());
3610 if (PromotionTypeCR.
isNull())
3611 PromotionTypeCR =
E->getComputationResultType();
3612 QualType PromotionTypeLHS = getPromotionType(
E->getComputationLHSType());
3614 if (!PromotionTypeRHS.
isNull())
3617 OpInfo.RHS = Visit(
E->getRHS());
3618 OpInfo.Ty = PromotionTypeCR;
3619 OpInfo.Opcode =
E->getOpcode();
3625 llvm::PHINode *atomicPHI =
nullptr;
3628 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3629 !(
type->isUnsignedIntegerType() &&
3630 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3633 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3634 llvm::Instruction::BinaryOps Op;
3635 switch (OpInfo.Opcode) {
3637 case BO_MulAssign:
case BO_DivAssign:
3643 AtomicOp = llvm::AtomicRMWInst::Add;
3644 Op = llvm::Instruction::Add;
3647 AtomicOp = llvm::AtomicRMWInst::Sub;
3648 Op = llvm::Instruction::Sub;
3651 AtomicOp = llvm::AtomicRMWInst::And;
3652 Op = llvm::Instruction::And;
3655 AtomicOp = llvm::AtomicRMWInst::Xor;
3656 Op = llvm::Instruction::Xor;
3659 AtomicOp = llvm::AtomicRMWInst::Or;
3660 Op = llvm::Instruction::Or;
3663 llvm_unreachable(
"Invalid compound assignment type");
3665 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3667 EmitScalarConversion(OpInfo.RHS,
E->getRHS()->
getType(), LHSTy,
3671 llvm::AtomicRMWInst *OldVal =
3676 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3682 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3684 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3686 Builder.CreateBr(opBB);
3687 Builder.SetInsertPoint(opBB);
3688 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3689 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3690 OpInfo.LHS = atomicPHI;
3693 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3695 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3697 if (!PromotionTypeLHS.
isNull())
3698 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3701 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3702 E->getComputationLHSType(),
Loc);
3717 ScalarConversionOpts(CGF.
SanOpts));
3720 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3724 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3725 llvm::Value *
success = Pair.second;
3726 atomicPHI->addIncoming(old, curBlock);
3727 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3728 Builder.SetInsertPoint(contBB);
3753 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3754 bool Ignore = TestAndClearIgnoreResultAssign();
3755 Value *RHS =
nullptr;
3756 LValue LHS = EmitCompoundAssignLValue(
E,
Func, RHS);
3774void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3775 const BinOpInfo &Ops, llvm::Value *Zero,
bool isDiv) {
3778 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3779 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
3780 SanitizerKind::IntegerDivideByZero));
3783 const auto *BO = cast<BinaryOperator>(Ops.E);
3784 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
3785 Ops.Ty->hasSignedIntegerRepresentation() &&
3787 Ops.mayHaveIntegerOverflow()) {
3788 llvm::IntegerType *Ty = cast<llvm::IntegerType>(
Zero->getType());
3790 llvm::Value *IntMin =
3791 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3792 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
3794 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
3795 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
3796 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
3798 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3801 if (Checks.size() > 0)
3802 EmitBinOpCheck(Checks, Ops);
3805Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
3807 CodeGenFunction::SanitizerScope SanScope(&CGF);
3808 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3809 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3810 Ops.Ty->isIntegerType() &&
3811 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3812 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3813 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
3814 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
3815 Ops.Ty->isRealFloatingType() &&
3816 Ops.mayHaveFloatDivisionByZero()) {
3817 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3818 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
3819 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3824 if (Ops.Ty->isConstantMatrixType()) {
3825 llvm::MatrixBuilder MB(Builder);
3828 auto *BO = cast<BinaryOperator>(Ops.E);
3832 "first operand must be a matrix");
3834 "second operand must be an arithmetic type");
3835 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3836 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3837 Ops.Ty->hasUnsignedIntegerRepresentation());
3840 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3842 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3843 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3847 else if (Ops.isFixedPointOp())
3848 return EmitFixedPointBinOp(Ops);
3849 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3850 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3852 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3855Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3857 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3858 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3859 Ops.Ty->isIntegerType() &&
3860 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3861 CodeGenFunction::SanitizerScope SanScope(&CGF);
3862 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3863 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3866 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3867 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3869 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3872Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3877 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3878 switch (Ops.Opcode) {
3882 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3883 llvm::Intrinsic::uadd_with_overflow;
3884 OverflowKind = SanitizerHandler::AddOverflow;
3889 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3890 llvm::Intrinsic::usub_with_overflow;
3891 OverflowKind = SanitizerHandler::SubOverflow;
3896 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3897 llvm::Intrinsic::umul_with_overflow;
3898 OverflowKind = SanitizerHandler::MulOverflow;
3901 llvm_unreachable(
"Unsupported operation for overflow detection");
3907 CodeGenFunction::SanitizerScope SanScope(&CGF);
3912 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3913 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3914 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3917 const std::string *handlerName =
3919 if (handlerName->empty()) {
3922 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3923 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3925 : SanitizerKind::UnsignedIntegerOverflow;
3926 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3928 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
3933 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3934 llvm::BasicBlock *continueBB =
3938 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3942 Builder.SetInsertPoint(overflowBB);
3945 llvm::Type *Int8Ty = CGF.
Int8Ty;
3946 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
3947 llvm::FunctionType *handlerTy =
3948 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3949 llvm::FunctionCallee handler =
3954 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
3955 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
3959 llvm::Value *handlerArgs[] = {
3962 Builder.getInt8(OpID),
3963 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3965 llvm::Value *handlerResult =
3969 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3970 Builder.CreateBr(continueBB);
3972 Builder.SetInsertPoint(continueBB);
3973 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3974 phi->addIncoming(result, initialBB);
3975 phi->addIncoming(handlerResult, overflowBB);
3982 const BinOpInfo &op,
3983 bool isSubtraction) {
3988 Value *pointer = op.LHS;
3989 Expr *pointerOperand =
expr->getLHS();
3990 Value *index = op.RHS;
3991 Expr *indexOperand =
expr->getRHS();
3994 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
3995 std::swap(pointer, index);
3996 std::swap(pointerOperand, indexOperand);
4001 unsigned width = cast<llvm::IntegerType>(index->
getType())->getBitWidth();
4003 auto PtrTy = cast<llvm::PointerType>(pointer->
getType());
4028 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4031 index = CGF.
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
4037 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
4039 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
4049 llvm::Value *objectSize
4052 index = CGF.
Builder.CreateMul(index, objectSize);
4071 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
4074 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
4076 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4095 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4106 bool negMul,
bool negAdd) {
4107 Value *MulOp0 = MulOp->getOperand(0);
4108 Value *MulOp1 = MulOp->getOperand(1);
4110 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4112 Addend = Builder.CreateFNeg(Addend,
"neg");
4114 Value *FMulAdd =
nullptr;
4115 if (Builder.getIsFPConstrained()) {
4116 assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
4117 "Only constrained operation should be created when Builder is in FP "
4118 "constrained mode");
4119 FMulAdd = Builder.CreateConstrainedFPCall(
4120 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4122 {MulOp0, MulOp1, Addend});
4124 FMulAdd = Builder.CreateCall(
4126 {MulOp0, MulOp1, Addend});
4128 MulOp->eraseFromParent();
4143 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4144 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4145 "Only fadd/fsub can be the root of an fmuladd.");
4148 if (!op.FPFeatures.allowFPContractWithinStatement())
4151 Value *LHS = op.LHS;
4152 Value *RHS = op.RHS;
4156 bool NegLHS =
false;
4157 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4158 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4159 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4160 LHS = LHSUnOp->getOperand(0);
4165 bool NegRHS =
false;
4166 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4167 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4168 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4169 RHS = RHSUnOp->getOperand(0);
4177 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4178 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4179 (LHSBinOp->use_empty() || NegLHS)) {
4182 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4183 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4186 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4187 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4188 (RHSBinOp->use_empty() || NegRHS)) {
4191 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4192 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4196 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4197 if (LHSBinOp->getIntrinsicID() ==
4198 llvm::Intrinsic::experimental_constrained_fmul &&
4199 (LHSBinOp->use_empty() || NegLHS)) {
4202 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4203 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4206 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4207 if (RHSBinOp->getIntrinsicID() ==
4208 llvm::Intrinsic::experimental_constrained_fmul &&
4209 (RHSBinOp->use_empty() || NegRHS)) {
4212 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4213 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4220Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4221 if (op.LHS->getType()->isPointerTy() ||
4222 op.RHS->getType()->isPointerTy())
4225 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4226 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4228 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4229 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4232 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4233 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4236 if (CanElideOverflowCheck(CGF.
getContext(), op))
4237 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4238 return EmitOverflowCheckedBinOp(op);
4243 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4244 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4250 if (op.Ty->isConstantMatrixType()) {
4251 llvm::MatrixBuilder MB(Builder);
4252 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4253 return MB.CreateAdd(op.LHS, op.RHS);
4256 if (op.Ty->isUnsignedIntegerType() &&
4257 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4258 !CanElideOverflowCheck(CGF.
getContext(), op))
4259 return EmitOverflowCheckedBinOp(op);
4261 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4262 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4263 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4266 if (op.isFixedPointOp())
4267 return EmitFixedPointBinOp(op);
4269 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4274Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4276 using llvm::ConstantInt;
4284 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4285 RHSTy = BinOp->getRHS()->getType();
4286 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4291 LHSTy = CAO->getComputationLHSType();
4292 ResultTy = CAO->getComputationResultType();
4294 LHSTy = BinOp->getLHS()->getType();
4295 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4296 LHSTy = UnOp->getSubExpr()->getType();
4297 RHSTy = UnOp->getSubExpr()->getType();
4300 Value *LHS = op.LHS;
4301 Value *RHS = op.RHS;
4306 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4310 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4311 switch (op.Opcode) {
4314 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4318 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4322 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4326 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4330 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4334 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4337 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4339 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4341 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4343 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4348 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4350 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4354 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4367 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4373 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4378Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4380 if (!op.LHS->getType()->isPointerTy()) {
4381 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4382 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4384 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4385 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4388 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4389 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4392 if (CanElideOverflowCheck(CGF.
getContext(), op))
4393 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4394 return EmitOverflowCheckedBinOp(op);
4399 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4400 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4406 if (op.Ty->isConstantMatrixType()) {
4407 llvm::MatrixBuilder MB(Builder);
4408 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4409 return MB.CreateSub(op.LHS, op.RHS);
4412 if (op.Ty->isUnsignedIntegerType() &&
4413 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4414 !CanElideOverflowCheck(CGF.
getContext(), op))
4415 return EmitOverflowCheckedBinOp(op);
4417 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4418 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4419 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4422 if (op.isFixedPointOp())
4423 return EmitFixedPointBinOp(op);
4425 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4430 if (!op.RHS->getType()->isPointerTy())
4437 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4439 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4440 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4444 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4446 llvm::Value *divisor =
nullptr;
4452 elementType = VlaSize.Type;
4453 divisor = VlaSize.NumElts;
4457 if (!eltSize.
isOne())
4473 if (elementSize.
isOne())
4482 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4485Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4487 llvm::IntegerType *Ty;
4488 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4489 Ty = cast<llvm::IntegerType>(VT->getElementType());
4491 Ty = cast<llvm::IntegerType>(LHS->
getType());
4496 llvm::Type *RHSTy = RHS->
getType();
4497 llvm::APInt RHSMax =
4498 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4499 :
llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4500 if (RHSMax.ult(Ty->getBitWidth()))
4501 return llvm::ConstantInt::get(RHSTy, RHSMax);
4502 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4506 const Twine &Name) {
4507 llvm::IntegerType *Ty;
4508 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4509 Ty = cast<llvm::IntegerType>(VT->getElementType());
4511 Ty = cast<llvm::IntegerType>(LHS->
getType());
4513 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4514 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4516 return Builder.CreateURem(
4517 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4520Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4522 if (Ops.isFixedPointOp())
4523 return EmitFixedPointBinOp(Ops);
4527 Value *RHS = Ops.RHS;
4528 if (Ops.LHS->getType() != RHS->
getType())
4529 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4531 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4532 Ops.Ty->hasSignedIntegerRepresentation() &&
4535 bool SanitizeUnsignedBase =
4536 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4537 Ops.Ty->hasUnsignedIntegerRepresentation();
4538 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4539 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4542 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4543 else if ((SanitizeBase || SanitizeExponent) &&
4544 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4545 CodeGenFunction::SanitizerScope SanScope(&CGF);
4547 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4548 llvm::Value *WidthMinusOne =
4549 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4550 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4552 if (SanitizeExponent) {
4554 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
4561 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4564 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4565 llvm::Value *PromotedWidthMinusOne =
4566 (RHS == Ops.RHS) ? WidthMinusOne
4567 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4569 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4570 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4573 if (SanitizeUnsignedBase || CGF.
getLangOpts().CPlusPlus) {
4579 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4580 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4582 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4583 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
4585 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4586 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4587 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4588 Checks.push_back(std::make_pair(
4589 BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4590 : SanitizerKind::UnsignedShiftBase));
4593 assert(!Checks.empty());
4594 EmitBinOpCheck(Checks, Ops);
4597 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4600Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4602 if (Ops.isFixedPointOp())
4603 return EmitFixedPointBinOp(Ops);
4607 Value *RHS = Ops.RHS;
4608 if (Ops.LHS->getType() != RHS->
getType())
4609 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4613 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4614 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4615 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4616 CodeGenFunction::SanitizerScope SanScope(&CGF);
4617 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4618 llvm::Value *Valid = Builder.CreateICmpULE(
4619 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4620 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
4623 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4624 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4625 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4633 default: llvm_unreachable(
"unexpected element type");
4634 case BuiltinType::Char_U:
4635 case BuiltinType::UChar:
4636 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4637 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4638 case BuiltinType::Char_S:
4639 case BuiltinType::SChar:
4640 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4641 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4642 case BuiltinType::UShort:
4643 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4644 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4645 case BuiltinType::Short:
4646 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4647 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4648 case BuiltinType::UInt:
4649 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4650 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4651 case BuiltinType::Int:
4652 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4653 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4654 case BuiltinType::ULong:
4655 case BuiltinType::ULongLong:
4656 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4657 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4658 case BuiltinType::Long:
4659 case BuiltinType::LongLong:
4660 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4661 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4662 case BuiltinType::Float:
4663 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4664 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4665 case BuiltinType::Double:
4666 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4667 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4668 case BuiltinType::UInt128:
4669 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4670 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4671 case BuiltinType::Int128:
4672 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4673 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4678 llvm::CmpInst::Predicate UICmpOpc,
4679 llvm::CmpInst::Predicate SICmpOpc,
4680 llvm::CmpInst::Predicate FCmpOpc,
4682 TestAndClearIgnoreResultAssign();
4687 assert(
E->getOpcode() == BO_EQ ||
4688 E->getOpcode() == BO_NE);
4692 CGF, LHS, RHS, MPT,
E->getOpcode() == BO_NE);
4694 BinOpInfo BOInfo = EmitBinOps(
E);
4695 Value *LHS = BOInfo.LHS;
4696 Value *RHS = BOInfo.RHS;
4702 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4704 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4707 Value *FirstVecArg = LHS,
4708 *SecondVecArg = RHS;
4713 switch(
E->getOpcode()) {
4714 default: llvm_unreachable(
"is not a comparison operation");
4726 std::swap(FirstVecArg, SecondVecArg);
4733 if (ElementKind == BuiltinType::Float) {
4735 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4736 std::swap(FirstVecArg, SecondVecArg);
4744 if (ElementKind == BuiltinType::Float) {
4746 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4751 std::swap(FirstVecArg, SecondVecArg);
4756 Value *CR6Param = Builder.getInt32(CR6);
4758 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
4765 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(
Result->getType());
4766 if (ResultTy->getBitWidth() > 1 &&
4768 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
4773 if (BOInfo.isFixedPointOp()) {
4774 Result = EmitFixedPointBinOp(BOInfo);
4775 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
4776 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4778 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
4780 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
4782 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
4787 !isa<llvm::ConstantPointerNull>(LHS) &&
4788 !isa<llvm::ConstantPointerNull>(RHS)) {
4797 LHS = Builder.CreateStripInvariantGroup(LHS);
4799 RHS = Builder.CreateStripInvariantGroup(RHS);
4802 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
4808 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
4816 CETy = CTy->getElementType();
4818 LHS.first = Visit(
E->getLHS());
4819 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
4825 CTy->getElementType()) &&
4826 "The element types must always match.");
4829 RHS.first = Visit(
E->getRHS());
4830 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
4832 "The element types must always match.");
4835 Value *ResultR, *ResultI;
4839 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
4840 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
4844 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
4845 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
4848 if (
E->getOpcode() == BO_EQ) {
4849 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
4851 assert(
E->getOpcode() == BO_NE &&
4852 "Complex comparison other than == or != ?");
4853 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
4865 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E->getRHS())) {
4867 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
4868 *SrcType = ICE->getSubExpr()->getType();
4880 bool Ignore = TestAndClearIgnoreResultAssign();
4899 RHS = Visit(
E->getRHS());
4915 RHS = Visit(
E->getRHS());
4958 Value *LHS = Visit(
E->getLHS());
4959 Value *RHS = Visit(
E->getRHS());
4961 if (LHS->
getType()->isFPOrFPVectorTy()) {
4962 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4964 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4965 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4967 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4968 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4970 Value *
And = Builder.CreateAnd(LHS, RHS);
4971 return Builder.CreateSExt(
And, ConvertType(
E->
getType()),
"sext");
4975 llvm::Type *ResTy = ConvertType(
E->
getType());
4996 if (InstrumentRegions &&
5001 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
5014 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5019 return llvm::Constant::getNullValue(ResTy);
5031 CodeGenFunction::ConditionalEvaluation eval(CGF);
5040 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5042 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5044 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5053 RHSBlock = Builder.GetInsertBlock();
5058 if (InstrumentRegions &&
5062 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5066 PN->addIncoming(RHSCond, RHSBlockCnt);
5076 PN->addIncoming(RHSCond, RHSBlock);
5086 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5090 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5098 Value *LHS = Visit(
E->getLHS());
5099 Value *RHS = Visit(
E->getRHS());
5101 if (LHS->
getType()->isFPOrFPVectorTy()) {
5102 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5104 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
5105 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
5107 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
5108 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
5110 Value *
Or = Builder.CreateOr(LHS, RHS);
5111 return Builder.CreateSExt(
Or, ConvertType(
E->
getType()),
"sext");
5115 llvm::Type *ResTy = ConvertType(
E->
getType());
5136 if (InstrumentRegions &&
5141 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5154 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5159 return llvm::ConstantInt::get(ResTy, 1);
5171 CodeGenFunction::ConditionalEvaluation eval(CGF);
5181 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5183 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5185 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5197 RHSBlock = Builder.GetInsertBlock();
5202 if (InstrumentRegions &&
5206 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5210 PN->addIncoming(RHSCond, RHSBlockCnt);
5216 PN->addIncoming(RHSCond, RHSBlock);
5224 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5230 return Visit(
E->getRHS());
5255Value *ScalarExprEmitter::
5257 TestAndClearIgnoreResultAssign();
5260 CodeGenFunction::OpaqueValueMapping binding(CGF,
E);
5262 Expr *condExpr =
E->getCond();
5263 Expr *lhsExpr =
E->getTrueExpr();
5264 Expr *rhsExpr =
E->getFalseExpr();
5270 Expr *live = lhsExpr, *dead = rhsExpr;
5271 if (!CondExprBool) std::swap(live, dead);
5301 llvm::Value *LHS = Visit(lhsExpr);
5302 llvm::Value *RHS = Visit(rhsExpr);
5304 llvm::Type *condType = ConvertType(condExpr->
getType());
5305 auto *vecTy = cast<llvm::FixedVectorType>(condType);
5307 unsigned numElem = vecTy->getNumElements();
5308 llvm::Type *elemType = vecTy->getElementType();
5310 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5311 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5312 llvm::Value *tmp = Builder.CreateSExt(
5313 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5314 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5317 llvm::Value *RHSTmp = RHS;
5318 llvm::Value *LHSTmp = LHS;
5319 bool wasCast =
false;
5320 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
5321 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5322 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5323 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5327 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5328 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5329 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5331 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5341 llvm::Value *LHS = Visit(lhsExpr);
5342 llvm::Value *RHS = Visit(rhsExpr);
5344 llvm::Type *CondType = ConvertType(condExpr->
getType());
5345 auto *VecTy = cast<llvm::VectorType>(CondType);
5346 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5348 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5349 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5358 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5367 llvm::Value *LHS = Visit(lhsExpr);
5368 llvm::Value *RHS = Visit(rhsExpr);
5371 assert(!RHS &&
"LHS and RHS types must match");
5374 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5385 CodeGenFunction::ConditionalEvaluation eval(CGF);
5403 Value *LHS = Visit(lhsExpr);
5406 LHSBlock = Builder.GetInsertBlock();
5407 Builder.CreateBr(ContBlock);
5421 Value *RHS = Visit(rhsExpr);
5424 RHSBlock = Builder.GetInsertBlock();
5434 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5435 PN->addIncoming(LHS, LHSBlock);
5436 PN->addIncoming(RHS, RHSBlock);
5447 return Visit(
E->getChosenSubExpr());
5462Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5468 Value *Src,
unsigned NumElementsDst) {
5469 static constexpr int Mask[] = {0, 1, 2, -1};
5470 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5490 const llvm::DataLayout &DL,
5491 Value *Src, llvm::Type *DstTy,
5492 StringRef Name =
"") {
5496 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5497 return Builder.CreateBitCast(Src, DstTy, Name);
5500 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5501 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5504 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5506 if (!DstTy->isIntegerTy())
5507 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5509 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5513 if (!SrcTy->isIntegerTy())
5514 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5516 return Builder.CreateIntToPtr(Src, DstTy, Name);
5521 llvm::Type *DstTy = ConvertType(
E->
getType());
5523 llvm::Type *SrcTy = Src->
getType();
5524 unsigned NumElementsSrc =
5525 isa<llvm::VectorType>(SrcTy)
5526 ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5528 unsigned NumElementsDst =
5529 isa<llvm::VectorType>(DstTy)
5530 ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5539 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5544 Src->setName(
"astype");
5551 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5552 auto *Vec4Ty = llvm::FixedVectorType::get(
5553 cast<llvm::VectorType>(DstTy)->getElementType(), 4);
5558 Src->setName(
"astype");
5563 Src, DstTy,
"astype");
5578 "Invalid scalar expression to emit");
5580 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5581 .Visit(
const_cast<Expr *
>(
E));
5590 "Invalid scalar expression to emit");
5591 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy,
Loc);
5601 "Invalid complex -> scalar conversion");
5602 return ScalarExprEmitter(*
this)
5603 .EmitComplexToScalarConversion(Src, SrcTy, DstTy,
Loc);
5610 if (!PromotionType.
isNull())
5611 return ScalarExprEmitter(*this).EmitPromoted(
E, PromotionType);
5613 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(
E));
5619 bool isInc,
bool isPre) {
5620 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(
E, LV, isInc, isPre);
5627 Expr *BaseExpr =
E->getBase();
5630 llvm::Type *BaseTy =
5645 ScalarExprEmitter
Scalar(*
this);
5647 switch (
E->getOpcode()) {
5648#define COMPOUND_OP(Op) \
5649 case BO_##Op##Assign: \
5650 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5687 llvm_unreachable(
"Not valid compound assignment operators");
5690 llvm_unreachable(
"Unhandled compound assignment operator");
5705 llvm::LLVMContext &VMContext,
5711 llvm::Value *TotalOffset =
nullptr;
5714 if (isa<llvm::Constant>(GEPVal)) {
5717 Value *BasePtr_int =
5718 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
5720 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
5721 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5722 return {TotalOffset, Builder.getFalse()};
5725 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5726 assert(GEP->getPointerOperand() == BasePtr &&
5727 "BasePtr must be the base of the GEP.");
5728 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
5730 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
5733 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5734 auto *SAddIntrinsic =
5735 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
5736 auto *SMulIntrinsic =
5737 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
5740 llvm::Value *OffsetOverflows = Builder.getFalse();
5744 llvm::Value *RHS) -> llvm::Value * {
5745 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
5748 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
5749 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
5751 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
5754 OffsetOverflows = Builder.getTrue();
5755 return llvm::ConstantInt::get(VMContext, N);
5760 auto *ResultAndOverflow = Builder.CreateCall(
5761 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
5762 OffsetOverflows = Builder.CreateOr(
5763 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
5764 return Builder.CreateExtractValue(ResultAndOverflow, 0);
5768 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
5769 GTI != GTE; ++GTI) {
5770 llvm::Value *LocalOffset;
5771 auto *Index = GTI.getOperand();
5773 if (
auto *STy = GTI.getStructTypeOrNull()) {
5776 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
5777 LocalOffset = llvm::ConstantInt::get(
5778 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
5783 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
5784 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
5785 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
5790 if (!TotalOffset || TotalOffset == Zero)
5791 TotalOffset = LocalOffset;
5793 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
5796 return {TotalOffset, OffsetOverflows};
5802 bool SignedIndices,
bool IsSubtraction,
5804 llvm::Type *PtrTy = Ptr->
getType();
5806 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
5808 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
5813 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5817 bool PerformNullCheck = !NullPointerIsDefined(
5818 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5821 bool PerformOverflowCheck =
5822 !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5824 if (!(PerformNullCheck || PerformOverflowCheck))
5829 SanitizerScope SanScope(
this);
5830 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
5835 assert((!isa<llvm::Constant>(EvaluatedGEP.
TotalOffset) ||
5837 "If the offset got constant-folded, we don't expect that there was an "
5840 auto *
Zero = llvm::ConstantInt::getNullValue(
IntPtrTy);
5854 if (PerformNullCheck) {
5866 auto *BaseIsNotNullptr =
Builder.CreateIsNotNull(Ptr);
5867 auto *ResultIsNotNullptr =
Builder.CreateIsNotNull(ComputedGEP);
5870 ?
Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5871 :
Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5872 Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5875 if (PerformOverflowCheck) {
5880 llvm::Value *ValidGEP;
5882 if (SignedIndices) {
5888 auto *PosOrZeroValid =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5889 auto *PosOrZeroOffset =
5891 llvm::Value *NegValid =
Builder.CreateICmpULT(ComputedGEP, IntPtr);
5893 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5899 ValidGEP =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5905 ValidGEP =
Builder.CreateICmpULE(ComputedGEP, IntPtr);
5907 ValidGEP =
Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5908 Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5911 assert(!Checks.empty() &&
"Should have produced some checks.");
5915 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5916 EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
5924 const Twine &Name) {
5925 if (!
SanOpts.
has(SanitizerKind::PointerOverflow)) {
5926 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
5928 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
5930 return Builder.
CreateGEP(Addr, IdxList, elementType, Align, Name, NWFlags);
5936 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 bool matchesPostDecrInWhile(const UnaryOperator *UO, bool isInc, bool isPre, ASTContext &Ctx)
For the purposes of overflow pattern exclusion, does this match the "while(i--)" pattern?
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)
static QualType getPointeeType(const MemRegion *R)
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.
ParentMapContext & getParentMapContext()
Returns the dynamic AST node parent map context.
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.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
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...
AddrLabelExpr - The GNU address of label extension, representing &&label.
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.
QualType getElementType() const
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
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
bool isShiftAssignOp() const
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.
An expression "T()" which creates an rvalue of a non-class type T.
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]).
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.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
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="")
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 EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
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.
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
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.
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...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
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.
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::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)
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.
llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
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)
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
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::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
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::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() const
const CGBitFieldInfo & getBitFieldInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
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.
CompoundLiteralExpr - [C99 6.5.2.5].
Represents the specialization of a concept - evaluates to a prvalue of type bool.
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...
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.
Represents a reference to #emded data.
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.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
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...
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
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.
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.
@ PostDecrInWhile
while (count–)
bool isSignedOverflowDefined() const
bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) 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.
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.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
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,...
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.
This expression type represents an asterisk in an OpenACC Size-Expr, used in the 'tile' and 'gang' cl...
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
DynTypedNodeList getParents(const NodeT &Node)
Returns the parents of the given node (within the traversal scope).
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...
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.
Represents an expression that computes the length of a 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;}).
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...
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
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 isBuiltinType() const
Helper methods to distinguish type categories.
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.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
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
WhileStmt - This represents a 'while' stmt.
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 Load(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.