35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/ADT/ScopeExit.h"
37#include "llvm/IR/Argument.h"
38#include "llvm/IR/CFG.h"
39#include "llvm/IR/Constants.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/DerivedTypes.h"
42#include "llvm/IR/FixedPointBuilder.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/GEPNoWrapFlags.h"
45#include "llvm/IR/GetElementPtrTypeIterator.h"
46#include "llvm/IR/GlobalVariable.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/IntrinsicsPowerPC.h"
49#include "llvm/IR/MatrixBuilder.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/TypeSize.h"
74bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
76 llvm::APInt &Result) {
79 const auto &LHSAP = LHS->getValue();
80 const auto &RHSAP = RHS->getValue();
81 if (Opcode == BO_Add) {
82 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
83 : LHSAP.uadd_ov(RHSAP, Overflow);
84 }
else if (Opcode == BO_Sub) {
85 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
86 : LHSAP.usub_ov(RHSAP, Overflow);
87 }
else if (Opcode == BO_Mul) {
88 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
89 : LHSAP.umul_ov(RHSAP, Overflow);
90 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
91 if (
Signed && !RHS->isZero())
92 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
104 FPOptions FPFeatures;
108 bool mayHaveIntegerOverflow()
const {
110 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
111 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
112 if (!LHSCI || !RHSCI)
116 return ::mayHaveIntegerOverflow(
121 bool isDivremOp()
const {
127 bool mayHaveIntegerDivisionByZero()
const {
129 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
135 bool mayHaveFloatDivisionByZero()
const {
137 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
138 return CFP->isZero();
145 bool isFixedPointOp()
const {
148 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
149 QualType LHSType = BinOp->getLHS()->getType();
150 QualType RHSType = BinOp->getRHS()->getType();
153 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
154 return UnOp->getSubExpr()->getType()->isFixedPointType();
159 bool rhsHasSignedIntegerRepresentation()
const {
160 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
161 QualType RHSType = BinOp->getRHS()->getType();
168static bool MustVisitNullValue(
const Expr *E) {
191static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
196static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
198 "Expected a unary or binary operator");
202 if (!Op.mayHaveIntegerOverflow())
205 if (Op.Ty->isSignedIntegerType() &&
211 if (Op.Ty->isUnsignedIntegerType() &&
232 if (BO->hasExcludedOverflowPattern())
248 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
254 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
255 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
259class ScalarExprEmitter
261 CodeGenFunction &CGF;
262 CGBuilderTy &Builder;
263 bool IgnoreResultAssign;
264 llvm::LLVMContext &VMContext;
267 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
268 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
269 VMContext(cgf.getLLVMContext()) {
276 bool TestAndClearIgnoreResultAssign() {
277 bool I = IgnoreResultAssign;
278 IgnoreResultAssign =
false;
282 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
283 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
289 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
290 const BinOpInfo &Info);
292 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
296 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
297 const AlignValueAttr *AVAttr =
nullptr;
298 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
299 const ValueDecl *VD = DRE->getDecl();
302 if (
const auto *TTy =
304 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
314 AVAttr = VD->
getAttr<AlignValueAttr>();
319 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
320 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
333 Value *EmitLoadOfLValue(
const Expr *E) {
337 EmitLValueAlignmentAssumption(E,
V);
343 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
347 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
348 Value *Src, QualType SrcType, QualType DstType,
349 llvm::Type *DstTy, SourceLocation Loc);
354 enum ImplicitConversionCheckKind :
unsigned char {
355 ICCK_IntegerTruncation = 0,
356 ICCK_UnsignedIntegerTruncation = 1,
357 ICCK_SignedIntegerTruncation = 2,
358 ICCK_IntegerSignChange = 3,
359 ICCK_SignedIntegerTruncationOrSignChange = 4,
364 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
365 QualType DstType, SourceLocation Loc);
370 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
371 QualType DstType, SourceLocation Loc);
375 struct ScalarConversionOpts {
376 bool TreatBooleanAsSigned;
377 bool EmitImplicitIntegerTruncationChecks;
378 bool EmitImplicitIntegerSignChangeChecks;
380 ScalarConversionOpts()
381 : TreatBooleanAsSigned(
false),
382 EmitImplicitIntegerTruncationChecks(
false),
383 EmitImplicitIntegerSignChangeChecks(
false) {}
385 ScalarConversionOpts(clang::SanitizerSet SanOpts)
386 : TreatBooleanAsSigned(
false),
387 EmitImplicitIntegerTruncationChecks(
388 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
389 EmitImplicitIntegerSignChangeChecks(
390 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)) {}
392 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
393 llvm::Type *SrcTy, llvm::Type *DstTy,
394 ScalarConversionOpts Opts);
396 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
398 ScalarConversionOpts Opts = ScalarConversionOpts());
402 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
408 QualType SrcTy, QualType DstTy,
412 Value *EmitNullValue(QualType Ty);
417 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
418 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
422 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
425 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
432 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
433 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
439 ZI->eraseFromParent();
444 return Builder.CreateIsNotNull(
V,
"tobool");
451 Value *Visit(Expr *E) {
452 ApplyDebugLocation DL(CGF, E);
453 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
456 Value *VisitStmt(Stmt *S) {
458 llvm_unreachable(
"Stmt can't have complex result type!");
460 Value *VisitExpr(Expr *S);
462 Value *VisitConstantExpr(ConstantExpr *E) {
468 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
483 Value *VisitParenExpr(ParenExpr *PE) {
486 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
489 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
490 return Visit(
GE->getResultExpr());
492 Value *VisitCoawaitExpr(CoawaitExpr *S) {
495 Value *VisitCoyieldExpr(CoyieldExpr *S) {
498 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
503 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
504 return Builder.getInt(E->
getValue());
506 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
507 return Builder.getInt(E->
getValue());
509 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
510 return llvm::ConstantFP::get(VMContext, E->
getValue());
512 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
513 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
515 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
516 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
518 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
519 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
521 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
525 return EmitNullValue(E->
getType());
527 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
528 return EmitNullValue(E->
getType());
530 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
531 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
532 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
534 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
537 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
541 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
545 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
546 Value *VisitEmbedExpr(EmbedExpr *E);
548 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
557 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
558 llvm_unreachable(
"Codegen for this isn't defined/implemented");
562 Value *VisitDeclRefExpr(DeclRefExpr *E) {
565 return EmitLoadOfLValue(E);
568 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
571 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
574 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
575 return EmitLoadOfLValue(E);
577 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
580 return EmitLoadOfLValue(E);
584 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
590 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
596 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
601 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
602 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
603 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
604 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
605 Value *VisitMemberExpr(MemberExpr *E);
606 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
607 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
613 return EmitLoadOfLValue(E);
616 Value *VisitInitListExpr(InitListExpr *E);
618 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
620 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
624 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
625 return EmitNullValue(E->
getType());
627 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
629 return VisitCastExpr(E);
633 Value *VisitCallExpr(
const CallExpr *E) {
635 return EmitLoadOfLValue(E);
639 EmitLValueAlignmentAssumption(E,
V);
643 Value *VisitStmtExpr(
const StmtExpr *E);
646 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
648 return EmitScalarPrePostIncDec(E, LV,
false,
false);
650 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
652 return EmitScalarPrePostIncDec(E, LV,
true,
false);
654 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
656 return EmitScalarPrePostIncDec(E, LV,
false,
true);
658 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
660 return EmitScalarPrePostIncDec(E, LV,
true,
true);
663 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
667 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
668 bool isInc,
bool isPre);
671 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
675 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
677 Value *VisitUnaryDeref(
const UnaryOperator *E) {
680 return EmitLoadOfLValue(E);
683 Value *VisitUnaryPlus(
const UnaryOperator *E,
684 QualType PromotionType = QualType());
685 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
686 Value *VisitUnaryMinus(
const UnaryOperator *E,
687 QualType PromotionType = QualType());
688 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
690 Value *VisitUnaryNot (
const UnaryOperator *E);
691 Value *VisitUnaryLNot (
const UnaryOperator *E);
692 Value *VisitUnaryReal(
const UnaryOperator *E,
693 QualType PromotionType = QualType());
694 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
695 Value *VisitUnaryImag(
const UnaryOperator *E,
696 QualType PromotionType = QualType());
697 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
698 Value *VisitUnaryExtension(
const UnaryOperator *E) {
703 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
704 return EmitLoadOfLValue(E);
706 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
714 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
715 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
718 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
719 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
722 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
726 Value *VisitExprWithCleanups(ExprWithCleanups *E);
727 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
730 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
735 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
737 return llvm::ConstantInt::get(ConvertType(E->
getType()),
740 return llvm::ConstantInt::get(ConvertType(E->
getType()),
744 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
752 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
753 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
756 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
757 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
760 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
770 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
771 return EmitNullValue(E->
getType());
774 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
779 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
780 return Builder.getInt1(E->
getValue());
784 Value *EmitMul(
const BinOpInfo &Ops) {
785 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
786 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
787 case LangOptions::SOB_Defined:
788 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
789 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
791 case LangOptions::SOB_Undefined:
792 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
793 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
795 case LangOptions::SOB_Trapping:
796 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
797 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
798 return EmitOverflowCheckedBinOp(Ops);
802 if (Ops.Ty->isConstantMatrixType()) {
803 llvm::MatrixBuilder MB(Builder);
807 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
808 BO->getLHS()->getType().getCanonicalType());
809 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
810 BO->getRHS()->getType().getCanonicalType());
811 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
812 if (LHSMatTy && RHSMatTy)
813 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
814 LHSMatTy->getNumColumns(),
815 RHSMatTy->getNumColumns());
816 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
819 if (Ops.Ty->isUnsignedIntegerType() &&
820 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
821 !CanElideOverflowCheck(CGF.
getContext(), Ops))
822 return EmitOverflowCheckedBinOp(Ops);
824 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
826 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
827 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
829 if (Ops.isFixedPointOp())
830 return EmitFixedPointBinOp(Ops);
831 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
835 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
838 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
839 llvm::Value *
Zero,
bool isDiv);
841 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
847 Value *EmitDiv(
const BinOpInfo &Ops);
848 Value *EmitRem(
const BinOpInfo &Ops);
849 Value *EmitAdd(
const BinOpInfo &Ops);
850 Value *EmitSub(
const BinOpInfo &Ops);
851 Value *EmitShl(
const BinOpInfo &Ops);
852 Value *EmitShr(
const BinOpInfo &Ops);
853 Value *EmitAnd(
const BinOpInfo &Ops) {
854 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
856 Value *EmitXor(
const BinOpInfo &Ops) {
857 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
859 Value *EmitOr (
const BinOpInfo &Ops) {
860 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
864 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
866 BinOpInfo EmitBinOps(
const BinaryOperator *E,
867 QualType PromotionTy = QualType());
869 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
870 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
871 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
873 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
874 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
877 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
878 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
880 QualType getPromotionType(QualType Ty) {
882 if (
auto *CT = Ty->
getAs<ComplexType>()) {
883 QualType ElementType = CT->getElementType();
889 if (
auto *VT = Ty->
getAs<VectorType>()) {
890 unsigned NumElements = VT->getNumElements();
900#define HANDLEBINOP(OP) \
901 Value *VisitBin##OP(const BinaryOperator *E) { \
902 QualType promotionTy = getPromotionType(E->getType()); \
903 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
904 if (result && !promotionTy.isNull()) \
905 result = EmitUnPromotedValue(result, E->getType()); \
908 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
909 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
910 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
926 llvm::CmpInst::Predicate SICmpOpc,
927 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
928#define VISITCOMP(CODE, UI, SI, FP, SIG) \
929 Value *VisitBin##CODE(const BinaryOperator *E) { \
930 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
931 llvm::FCmpInst::FP, SIG); }
932 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
946 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
947 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
949 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
954 Value *VisitBlockExpr(
const BlockExpr *BE);
955 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
956 Value *VisitChooseExpr(ChooseExpr *CE);
957 Value *VisitVAArgExpr(VAArgExpr *VE);
958 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
961 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
964 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
967 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
970 Value *VisitAsTypeExpr(AsTypeExpr *CE);
971 Value *VisitAtomicExpr(AtomicExpr *AE);
972 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
985 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
988 return EmitFloatToBoolConversion(Src);
990 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
994 "Unknown scalar type to convert");
997 return EmitIntToBoolConversion(Src);
1000 return EmitPointerToBoolConversion(Src, SrcType);
1003void ScalarExprEmitter::EmitFloatConversionCheck(
1004 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1005 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1006 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1010 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1011 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1012 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1013 using llvm::APFloat;
1016 llvm::Value *Check =
nullptr;
1017 const llvm::fltSemantics &SrcSema =
1027 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1028 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1029 APFloat::opOverflow)
1032 MinSrc = APFloat::getInf(SrcSema,
true);
1036 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1039 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1040 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1041 APFloat::opOverflow)
1044 MaxSrc = APFloat::getInf(SrcSema,
false);
1048 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1053 const llvm::fltSemantics &Sema =
1056 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1057 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1061 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1063 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1064 Check = Builder.CreateAnd(GE, LE);
1069 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1075static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1076 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1079 llvm::Type *SrcTy = Src->
getType();
1080 llvm::Type *DstTy = Dst->
getType();
1085 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1087 "non-integer llvm type");
1094 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1096 if (!SrcSigned && !DstSigned) {
1097 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1098 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1100 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1101 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1104 llvm::Value *Check =
nullptr;
1106 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1108 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1110 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1118void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1119 Value *Dst, QualType DstType,
1120 SourceLocation Loc) {
1130 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1131 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1133 if (SrcBits <= DstBits)
1136 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1143 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1144 (!SrcSigned && DstSigned))
1147 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1148 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1151 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1156 SanitizerDebugLocation SanScope(
1158 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1159 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1170 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1177 llvm::Constant *StaticArgs[] = {
1180 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1181 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1183 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1190 llvm::Type *VTy =
V->getType();
1193 return llvm::ConstantInt::getFalse(VTy->getContext());
1195 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1196 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1197 llvm::Twine(Name) +
"." +
V->getName() +
1198 ".negativitycheck");
1203static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1204 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1207 llvm::Type *SrcTy = Src->
getType();
1208 llvm::Type *DstTy = Dst->
getType();
1211 "non-integer llvm type");
1217 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1218 unsigned DstBits = DstTy->getScalarSizeInBits();
1222 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1223 "either the widths should be different, or the signednesses.");
1226 llvm::Value *SrcIsNegative =
1229 llvm::Value *DstIsNegative =
1235 llvm::Value *Check =
nullptr;
1236 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1238 return std::make_pair(
1239 ScalarExprEmitter::ICCK_IntegerSignChange,
1240 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1243void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1244 Value *Dst, QualType DstType,
1245 SourceLocation Loc) {
1246 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange))
1249 llvm::Type *SrcTy = Src->
getType();
1250 llvm::Type *DstTy = Dst->
getType();
1260 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1261 unsigned DstBits = DstTy->getScalarSizeInBits();
1268 if (SrcSigned == DstSigned && SrcBits == DstBits)
1272 if (!SrcSigned && !DstSigned)
1277 if ((DstBits > SrcBits) && DstSigned)
1279 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1280 (SrcBits > DstBits) && SrcSigned) {
1289 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1293 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1297 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1298 SanitizerDebugLocation SanScope(
1300 {SanitizerKind::SO_ImplicitIntegerSignChange,
1301 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1302 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1305 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1306 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1310 ImplicitConversionCheckKind CheckKind;
1311 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1318 CheckKind = Check.first;
1319 Checks.emplace_back(Check.second);
1321 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1322 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1328 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1329 Checks.emplace_back(Check.second);
1333 llvm::Constant *StaticArgs[] = {
1336 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1337 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1339 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1344static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1345 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1351 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1352 if (!SrcSigned && !DstSigned)
1353 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1355 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1357 llvm::Value *Check =
nullptr;
1359 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1361 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1364 return std::make_pair(
1366 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1371static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1372 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1376 llvm::Value *SrcIsNegative =
1379 llvm::Value *DstIsNegative =
1385 llvm::Value *Check =
nullptr;
1387 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1389 return std::make_pair(
1390 ScalarExprEmitter::ICCK_IntegerSignChange,
1391 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1399 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1417 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1418 unsigned DstBits = Info.
Size;
1423 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1425 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1427 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1428 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1432 bool EmitTruncation = DstBits < SrcBits;
1436 bool EmitTruncationFromUnsignedToSigned =
1437 EmitTruncation && DstSigned && !SrcSigned;
1439 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1440 bool BothUnsigned = !SrcSigned && !DstSigned;
1441 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1448 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1453 else if (EmitSignChange) {
1454 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1455 "either the widths should be different, or the signednesses.");
1461 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1462 if (EmitTruncationFromUnsignedToSigned)
1463 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1465 llvm::Constant *StaticArgs[] = {
1468 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1469 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1471 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1475 QualType DstType, llvm::Type *SrcTy,
1477 ScalarConversionOpts Opts) {
1479 llvm::Type *SrcElementTy;
1480 llvm::Type *DstElementTy;
1490 "cannot cast between matrix and non-matrix types");
1491 SrcElementTy = SrcTy;
1492 DstElementTy = DstTy;
1493 SrcElementType = SrcType;
1494 DstElementType = DstType;
1499 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1504 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1506 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1507 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1511 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1518 llvm::Intrinsic::ID IID =
1519 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1520 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1524 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1525 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1528 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1529 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1530 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1532 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1533 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1534 return Builder.CreateFPExt(Src, DstTy,
"conv");
1539Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1542 ScalarConversionOpts Opts) {
1557 return Builder.CreateIsNotNull(Src,
"tobool");
1560 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1563 "Unhandled scalar conversion from a fixed point type to another type.");
1567 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1570 "Unhandled scalar conversion to a fixed point type from another type.");
1573 QualType NoncanonicalSrcType = SrcType;
1574 QualType NoncanonicalDstType = DstType;
1578 if (SrcType == DstType)
return Src;
1582 llvm::Value *OrigSrc = Src;
1583 QualType OrigSrcType = SrcType;
1584 llvm::Type *SrcTy = Src->
getType();
1588 return EmitConversionToBool(Src, SrcType);
1590 llvm::Type *DstTy = ConvertType(DstType);
1595 if (DstTy->isFloatingPointTy()) {
1597 return Builder.CreateCall(
1605 Src = Builder.CreateCall(
1610 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1618 if (SrcTy == DstTy) {
1619 if (Opts.EmitImplicitIntegerSignChangeChecks)
1620 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1621 NoncanonicalDstType, Loc);
1629 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1634 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1639 llvm::Value* IntResult =
1640 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1642 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1648 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1655 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1657 "Splatted expr doesn't match with vector element type?");
1661 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1665 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1669 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1670 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1671 if (SrcSize == DstSize)
1672 return Builder.CreateBitCast(Src, DstTy,
"conv");
1685 assert(((SrcElementTy->isIntegerTy() &&
1686 DstElementTy->isIntegerTy()) ||
1687 (SrcElementTy->isFloatingPointTy() &&
1688 DstElementTy->isFloatingPointTy())) &&
1689 "unexpected conversion between a floating-point vector and an "
1693 if (SrcElementTy->isIntegerTy())
1694 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1697 if (SrcSize > DstSize)
1698 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1701 return Builder.CreateFPExt(Src, DstTy,
"conv");
1705 Value *Res =
nullptr;
1706 llvm::Type *ResTy = DstTy;
1713 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1715 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1721 if (SrcTy->isFloatingPointTy()) {
1725 return Builder.CreateCall(
1728 return Builder.CreateFPTrunc(Src, DstTy);
1733 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1735 if (DstTy != ResTy) {
1737 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1738 Res = Builder.CreateCall(
1742 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1746 if (Opts.EmitImplicitIntegerTruncationChecks)
1747 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1748 NoncanonicalDstType, Loc);
1750 if (Opts.EmitImplicitIntegerSignChangeChecks)
1751 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1752 NoncanonicalDstType, Loc);
1757Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1759 SourceLocation Loc) {
1760 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1763 Result = FPBuilder.CreateFloatingToFixed(Src,
1766 Result = FPBuilder.CreateFixedToFloating(Src,
1768 ConvertType(DstTy));
1774 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1775 DstFPSema.getWidth(),
1776 DstFPSema.isSigned());
1778 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1781 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1788Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1790 SourceLocation Loc) {
1792 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1797 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1798 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1799 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1806 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1809Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1817void ScalarExprEmitter::EmitBinOpCheck(
1818 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1819 const BinOpInfo &Info) {
1822 SmallVector<llvm::Constant *, 4> StaticData;
1823 SmallVector<llvm::Value *, 2> DynamicData;
1831 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1832 if (UO && UO->
getOpcode() == UO_Minus) {
1833 Check = SanitizerHandler::NegateOverflow;
1835 DynamicData.push_back(Info.RHS);
1839 Check = SanitizerHandler::ShiftOutOfBounds;
1841 StaticData.push_back(
1843 StaticData.push_back(
1845 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1847 Check = SanitizerHandler::DivremOverflow;
1851 int ArithOverflowKind = 0;
1854 Check = SanitizerHandler::AddOverflow;
1855 ArithOverflowKind = diag::UBSanArithKind::Add;
1859 Check = SanitizerHandler::SubOverflow;
1860 ArithOverflowKind = diag::UBSanArithKind::Sub;
1864 Check = SanitizerHandler::MulOverflow;
1865 ArithOverflowKind = diag::UBSanArithKind::Mul;
1869 llvm_unreachable(
"unexpected opcode for bin op check");
1873 SanitizerKind::UnsignedIntegerOverflow) ||
1875 SanitizerKind::SignedIntegerOverflow)) {
1879 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1883 DynamicData.push_back(Info.LHS);
1884 DynamicData.push_back(Info.RHS);
1887 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1894Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1902ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1904 unsigned AddrSpace =
1906 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1909 llvm::Type *ExprTy = ConvertType(E->
getType());
1910 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1914Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
1916 auto It = E->
begin();
1917 return Builder.getInt((*It)->getValue());
1920Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
1928 unsigned LHSElts = LTy->getNumElements();
1936 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1937 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1945 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1946 MTy->getNumElements());
1947 Value* NewV = llvm::PoisonValue::get(RTy);
1948 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1949 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1950 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1952 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1953 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1961 SmallVector<int, 32> Indices;
1965 if (Idx.isSigned() && Idx.isAllOnes())
1966 Indices.push_back(-1);
1968 Indices.push_back(Idx.getZExtValue());
1971 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1974Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
1982 if (SrcType == DstType)
return Src;
1985 "ConvertVector source type must be a vector");
1987 "ConvertVector destination type must be a vector");
1989 llvm::Type *SrcTy = Src->
getType();
1990 llvm::Type *DstTy = ConvertType(DstType);
1996 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
1997 DstEltType = DstType->
castAs<VectorType>()->getElementType();
1999 assert(SrcTy->isVectorTy() &&
2000 "ConvertVector source IR type must be a vector");
2001 assert(DstTy->isVectorTy() &&
2002 "ConvertVector destination IR type must be a vector");
2007 if (DstEltType->isBooleanType()) {
2008 assert((SrcEltTy->isFloatingPointTy() ||
2011 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2012 if (SrcEltTy->isFloatingPointTy()) {
2013 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2014 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2016 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2021 Value *Res =
nullptr;
2026 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2028 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2030 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2032 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2035 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2036 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2037 if (DstEltType->isSignedIntegerOrEnumerationType())
2038 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2040 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2042 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2043 "Unknown real conversion");
2044 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2045 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2046 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2048 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2054Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2063 return Builder.getInt(
Value);
2067 llvm::Value *
Result = EmitLoadOfLValue(E);
2073 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2074 if (llvm::GetElementPtrInst *GEP =
2075 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2076 if (llvm::Instruction *
Pointer =
2077 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2089Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2090 TestAndClearIgnoreResultAssign();
2098 return EmitLoadOfLValue(E);
2106 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2109 return Builder.CreateExtractElement(Base, Idx,
"vecext");
2112Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2113 TestAndClearIgnoreResultAssign();
2121 unsigned NumRows = MatrixTy->getNumRows();
2122 llvm::MatrixBuilder MB(Builder);
2123 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2125 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2130 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2135 int MV = SVI->getMaskValue(Idx);
2142 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2143 "Index operand too large for shufflevector mask!");
2144 return C->getZExtValue();
2147Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2148 bool Ignore = TestAndClearIgnoreResultAssign();
2151 assert((Ignore ==
false ||
2153 "init list ignored");
2170 llvm::VectorType *VType =
2171 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2174 if (NumInitElements == 0) {
2176 return EmitNullValue(E->
getType());
2183 if (NumInitElements == 0) {
2185 return EmitNullValue(E->
getType());
2188 if (NumInitElements == 1) {
2189 Expr *InitVector = E->
getInit(0);
2194 return Visit(InitVector);
2197 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2207 unsigned CurIdx = 0;
2208 bool VIsPoisonShuffle =
false;
2209 llvm::Value *
V = llvm::PoisonValue::get(VType);
2210 for (
unsigned i = 0; i != NumInitElements; ++i) {
2213 SmallVector<int, 16> Args;
2215 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2225 ->getNumElements() == ResElts) {
2227 Value *LHS =
nullptr, *RHS =
nullptr;
2232 Args.resize(ResElts, -1);
2234 LHS = EI->getVectorOperand();
2236 VIsPoisonShuffle =
true;
2237 }
else if (VIsPoisonShuffle) {
2240 for (
unsigned j = 0; j != CurIdx; ++j)
2242 Args.push_back(ResElts +
C->getZExtValue());
2243 Args.resize(ResElts, -1);
2246 RHS = EI->getVectorOperand();
2247 VIsPoisonShuffle =
false;
2249 if (!Args.empty()) {
2250 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2256 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2258 VIsPoisonShuffle =
false;
2268 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2271 Value *SVOp = SVI->getOperand(0);
2274 if (OpTy->getNumElements() == ResElts) {
2275 for (
unsigned j = 0; j != CurIdx; ++j) {
2278 if (VIsPoisonShuffle) {
2284 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2286 Args.resize(ResElts, -1);
2288 if (VIsPoisonShuffle)
2298 for (
unsigned j = 0; j != InitElts; ++j)
2300 Args.resize(ResElts, -1);
2301 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2304 for (
unsigned j = 0; j != CurIdx; ++j)
2306 for (
unsigned j = 0; j != InitElts; ++j)
2307 Args.push_back(j + Offset);
2308 Args.resize(ResElts, -1);
2315 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2322 llvm::Type *EltTy = VType->getElementType();
2325 for (; CurIdx < ResElts; ++CurIdx) {
2326 Value *Idx = Builder.getInt32(CurIdx);
2327 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2328 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2340 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2344 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2347 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2366 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2370 if (
const auto *CE = dyn_cast<CastExpr>(E))
2371 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2372 CE->getCastKind() == CK_ArrayToPointerDecay)
2383 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2393 if (ICE->isGLValue())
2408 assert(LoadList.size() >= VecTy->getNumElements() &&
2409 "Flattened type on RHS must have the same number or more elements "
2410 "than vector on LHS.");
2414 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2417 "All flattened source values should be scalars.");
2420 VecTy->getElementType(), Loc);
2421 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2426 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2427 "Flattened type on RHS must have the same number or more elements "
2428 "than vector on LHS.");
2433 for (
unsigned I = 0, E = MatTy->getNumElementsFlattened(); I < E; I++) {
2434 unsigned ColMajorIndex =
2435 (I % MatTy->getNumRows()) * MatTy->getNumColumns() +
2436 (I / MatTy->getNumRows());
2439 "All flattened source values should be scalars.");
2441 RVal.
getScalarVal(), LoadList[ColMajorIndex].getType(),
2442 MatTy->getElementType(), Loc);
2443 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2449 "Destination type must be a vector, matrix, or builtin type.");
2451 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2460 auto RestoreCurCast =
2461 llvm::make_scope_exit([
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2465 QualType DestTy = CE->
getType();
2467 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2471 bool Ignored = TestAndClearIgnoreResultAssign();
2477 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2478 case CK_BuiltinFnToFnPtr:
2479 llvm_unreachable(
"builtin functions are handled elsewhere");
2481 case CK_LValueBitCast:
2482 case CK_ObjCObjectLValueCast: {
2483 Address
Addr = EmitLValue(E).getAddress();
2486 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2489 case CK_LValueToRValueBitCast: {
2495 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2498 case CK_CPointerToObjCPointerCast:
2499 case CK_BlockPointerToObjCPointerCast:
2500 case CK_AnyPointerToBlockPointerCast:
2502 Value *Src = Visit(E);
2503 llvm::Type *SrcTy = Src->
getType();
2504 llvm::Type *DstTy = ConvertType(DestTy);
2515 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2520 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2521 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2522 "Address-space cast must be used to convert address spaces");
2524 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2525 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2527 PT->getPointeeType(),
2538 const QualType SrcType = E->
getType();
2543 Src = Builder.CreateLaunderInvariantGroup(Src);
2551 Src = Builder.CreateStripInvariantGroup(Src);
2556 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2560 if (!PointeeType.
isNull())
2569 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2570 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2573 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2574 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2575 ScalableDstTy = llvm::ScalableVectorType::get(
2576 FixedSrcTy->getElementType(),
2578 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2580 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2581 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2582 llvm::Value *
Result = Builder.CreateInsertVector(
2583 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2585 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2586 if (
Result->getType() != ScalableDstTy)
2588 if (
Result->getType() != DstTy)
2598 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2599 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2602 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2603 FixedDstTy->getElementType()->isIntegerTy(8)) {
2604 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2605 ScalableSrcTy = llvm::ScalableVectorType::get(
2606 ScalableSrcTy->getElementType(),
2608 ScalableSrcTy->getElementCount().getKnownMinValue()));
2609 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2610 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2614 ScalableSrcTy = llvm::ScalableVectorType::get(
2615 FixedDstTy->getElementType(),
2616 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2617 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2619 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2620 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2641 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2644 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2647 case CK_AddressSpaceConversion: {
2650 Result.Val.isNullPointer()) {
2654 if (
Result.HasSideEffects)
2657 ConvertType(DestTy)), DestTy);
2663 ConvertType(DestTy));
2665 case CK_AtomicToNonAtomic:
2666 case CK_NonAtomicToAtomic:
2667 case CK_UserDefinedConversion:
2674 case CK_BaseToDerived: {
2676 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2690 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2698 case CK_UncheckedDerivedToBase:
2699 case CK_DerivedToBase: {
2712 case CK_ArrayToPointerDecay:
2715 case CK_FunctionToPointerDecay:
2716 return EmitLValue(E).getPointer(CGF);
2718 case CK_NullToPointer:
2719 if (MustVisitNullValue(E))
2725 case CK_NullToMemberPointer: {
2726 if (MustVisitNullValue(E))
2729 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2733 case CK_ReinterpretMemberPointer:
2734 case CK_BaseToDerivedMemberPointer:
2735 case CK_DerivedToBaseMemberPointer: {
2736 Value *Src = Visit(E);
2747 case CK_ARCProduceObject:
2749 case CK_ARCConsumeObject:
2751 case CK_ARCReclaimReturnedObject:
2753 case CK_ARCExtendBlockObject:
2756 case CK_CopyAndAutoreleaseBlockObject:
2759 case CK_FloatingRealToComplex:
2760 case CK_FloatingComplexCast:
2761 case CK_IntegralRealToComplex:
2762 case CK_IntegralComplexCast:
2763 case CK_IntegralComplexToFloatingComplex:
2764 case CK_FloatingComplexToIntegralComplex:
2765 case CK_ConstructorConversion:
2767 case CK_HLSLArrayRValue:
2768 llvm_unreachable(
"scalar cast to non-scalar value");
2770 case CK_LValueToRValue:
2772 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2775 case CK_IntegralToPointer: {
2776 Value *Src = Visit(E);
2780 auto DestLLVMTy = ConvertType(DestTy);
2783 llvm::Value* IntResult =
2784 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2786 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2792 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2798 case CK_PointerToIntegral: {
2799 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2800 auto *PtrExpr = Visit(E);
2803 const QualType SrcType = E->
getType();
2808 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2812 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2818 case CK_MatrixCast: {
2819 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2826 case CK_HLSLAggregateSplatCast:
2827 case CK_VectorSplat: {
2828 llvm::Type *DstTy = ConvertType(DestTy);
2829 Value *Elt = Visit(E);
2831 llvm::ElementCount NumElements =
2833 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2836 case CK_FixedPointCast:
2837 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2840 case CK_FixedPointToBoolean:
2842 "Expected src type to be fixed point type");
2843 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2844 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2847 case CK_FixedPointToIntegral:
2849 "Expected src type to be fixed point type");
2850 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2851 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2854 case CK_IntegralToFixedPoint:
2856 "Expected src type to be an integer");
2858 "Expected dest type to be fixed point type");
2859 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2862 case CK_IntegralCast: {
2864 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2865 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
2869 ScalarConversionOpts Opts;
2870 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2871 if (!ICE->isPartOfExplicitCast())
2872 Opts = ScalarConversionOpts(CGF.
SanOpts);
2874 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2877 case CK_IntegralToFloating: {
2880 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2882 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
2883 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
2885 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2886 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2889 case CK_FloatingToIntegral: {
2892 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2894 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
2895 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
2897 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2898 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2901 case CK_FloatingCast: {
2904 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2905 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2906 if (DstElTy->
castAs<BuiltinType>()->getKind() <
2907 SrcElTy->
castAs<BuiltinType>()->getKind())
2908 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
2909 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
2911 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2912 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2915 case CK_FixedPointToFloating:
2916 case CK_FloatingToFixedPoint: {
2917 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2918 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2921 case CK_BooleanToSignedIntegral: {
2922 ScalarConversionOpts Opts;
2923 Opts.TreatBooleanAsSigned =
true;
2924 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2927 case CK_IntegralToBoolean:
2928 return EmitIntToBoolConversion(Visit(E));
2929 case CK_PointerToBoolean:
2930 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2931 case CK_FloatingToBoolean: {
2932 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2933 return EmitFloatToBoolConversion(Visit(E));
2935 case CK_MemberPointerToBoolean: {
2936 llvm::Value *MemPtr = Visit(E);
2937 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
2941 case CK_FloatingComplexToReal:
2942 case CK_IntegralComplexToReal:
2945 case CK_FloatingComplexToBoolean:
2946 case CK_IntegralComplexToBoolean: {
2950 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
2954 case CK_ZeroToOCLOpaqueType: {
2957 "CK_ZeroToOCLEvent cast on non-event type");
2958 return llvm::Constant::getNullValue(ConvertType(DestTy));
2961 case CK_IntToOCLSampler:
2964 case CK_HLSLVectorTruncation: {
2966 "Destination type must be a vector or builtin type.");
2967 Value *Vec = Visit(E);
2968 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
2969 SmallVector<int> Mask;
2970 unsigned NumElts = VecTy->getNumElements();
2971 for (
unsigned I = 0; I != NumElts; ++I)
2974 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2976 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
2977 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
2979 case CK_HLSLMatrixTruncation: {
2981 "Destination type must be a matrix or builtin type.");
2982 Value *Mat = Visit(E);
2983 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
2984 SmallVector<int> Mask;
2985 unsigned NumCols = MatTy->getNumColumns();
2986 unsigned NumRows = MatTy->getNumRows();
2987 unsigned ColOffset = NumCols;
2988 if (
auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>())
2989 ColOffset = SrcMatTy->getNumColumns();
2990 for (
unsigned R = 0; R < NumRows; R++) {
2991 for (
unsigned C = 0;
C < NumCols;
C++) {
2992 unsigned I = R * ColOffset +
C;
2997 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
2999 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3000 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3002 case CK_HLSLElementwiseCast: {
3022 llvm_unreachable(
"unknown scalar cast");
3025Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3026 CodeGenFunction::StmtExprEvaluation eval(CGF);
3035Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3036 CodeGenFunction::RunCleanupsScope Scope(CGF);
3040 Scope.ForceCleanup({&
V});
3049 llvm::Value *InVal,
bool IsInc,
3053 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3055 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3056 BinOp.FPFeatures = FPFeatures;
3061llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3062 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3063 llvm::Value *Amount =
3064 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
3065 StringRef Name = IsInc ?
"inc" :
"dec";
3066 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3067 case LangOptions::SOB_Defined:
3068 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3069 return Builder.CreateAdd(InVal, Amount, Name);
3071 case LangOptions::SOB_Undefined:
3072 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3073 return Builder.CreateNSWAdd(InVal, Amount, Name);
3075 case LangOptions::SOB_Trapping:
3079 return Builder.CreateNSWAdd(InVal, Amount, Name);
3080 return EmitOverflowCheckedBinOp(Info);
3082 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
3107class OMPLastprivateConditionalUpdateRAII {
3109 CodeGenFunction &CGF;
3110 const UnaryOperator *E;
3113 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3114 const UnaryOperator *E)
3116 ~OMPLastprivateConditionalUpdateRAII() {
3125ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3126 bool isInc,
bool isPre) {
3128 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3130 llvm::PHINode *atomicPHI =
nullptr;
3134 QualType SrcType = E->
getType();
3136 int amount = (isInc ? 1 : -1);
3137 bool isSubtraction = !isInc;
3139 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3140 type = atomicTy->getValueType();
3141 if (isInc &&
type->isBooleanType()) {
3144 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3145 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3146 return Builder.getTrue();
3150 return Builder.CreateAtomicRMW(
3151 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3152 llvm::AtomicOrdering::SequentiallyConsistent);
3157 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3158 !(
type->isUnsignedIntegerType() &&
3159 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3161 LangOptions::SOB_Trapping) {
3162 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3163 llvm::AtomicRMWInst::Sub;
3164 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3165 llvm::Instruction::Sub;
3167 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3169 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3170 llvm::AtomicOrdering::SequentiallyConsistent);
3171 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3175 if (
type->isFloatingType()) {
3176 llvm::Type *Ty = ConvertType(
type);
3177 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3178 llvm::AtomicRMWInst::BinOp aop =
3179 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3180 llvm::Instruction::BinaryOps op =
3181 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3182 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3183 llvm::AtomicRMWInst *old =
3185 llvm::AtomicOrdering::SequentiallyConsistent);
3187 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3190 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3193 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3196 Builder.CreateBr(opBB);
3197 Builder.SetInsertPoint(opBB);
3198 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3199 atomicPHI->addIncoming(value, startBB);
3202 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3213 if (isInc &&
type->isBooleanType()) {
3214 value = Builder.getTrue();
3217 }
else if (
type->isIntegerType()) {
3218 QualType promotedType;
3219 bool canPerformLossyDemotionCheck =
false;
3221 bool excludeOverflowPattern =
3226 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3227 canPerformLossyDemotionCheck =
true;
3228 canPerformLossyDemotionCheck &=
3231 canPerformLossyDemotionCheck &=
3233 type, promotedType);
3234 assert((!canPerformLossyDemotionCheck ||
3235 type->isSignedIntegerOrEnumerationType() ||
3237 ConvertType(
type)->getScalarSizeInBits() ==
3238 ConvertType(promotedType)->getScalarSizeInBits()) &&
3239 "The following check expects that if we do promotion to different "
3240 "underlying canonical type, at least one of the types (either "
3241 "base or promoted) will be signed, or the bitwidths will match.");
3244 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3245 SanitizerKind::ImplicitBitfieldConversion) &&
3246 canPerformLossyDemotionCheck) {
3260 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3261 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3262 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3266 ScalarConversionOpts Opts;
3267 if (!LV.isBitField())
3268 Opts = ScalarConversionOpts(CGF.
SanOpts);
3269 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3271 SrcType = promotedType;
3274 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3280 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
3281 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3283 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3284 !excludeOverflowPattern &&
3286 SanitizerKind::UnsignedIntegerOverflow, E->
getType())) {
3290 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3291 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3295 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3296 QualType
type = ptr->getPointeeType();
3299 if (
const VariableArrayType *vla
3302 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3305 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3308 elemTy, value, numElts,
false, isSubtraction,
3312 }
else if (
type->isFunctionType()) {
3313 llvm::Value *amt = Builder.getInt32(amount);
3316 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3320 false, isSubtraction,
3325 llvm::Value *amt = Builder.getInt32(amount);
3328 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3331 elemTy, value, amt,
false, isSubtraction,
3336 }
else if (
type->isVectorType()) {
3337 if (
type->hasIntegerRepresentation()) {
3338 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
3340 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3342 value = Builder.CreateFAdd(
3344 llvm::ConstantFP::get(value->getType(), amount),
3345 isInc ?
"inc" :
"dec");
3349 }
else if (
type->isRealFloatingType()) {
3352 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3357 value = Builder.CreateCall(
3360 input,
"incdec.conv");
3362 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3366 if (value->getType()->isFloatTy())
3367 amt = llvm::ConstantFP::get(VMContext,
3368 llvm::APFloat(
static_cast<float>(amount)));
3369 else if (value->getType()->isDoubleTy())
3370 amt = llvm::ConstantFP::get(VMContext,
3371 llvm::APFloat(
static_cast<double>(amount)));
3375 llvm::APFloat F(
static_cast<float>(amount));
3377 const llvm::fltSemantics *FS;
3380 if (value->getType()->isFP128Ty())
3382 else if (value->getType()->isHalfTy())
3384 else if (value->getType()->isBFloatTy())
3386 else if (value->getType()->isPPC_FP128Ty())
3390 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3391 amt = llvm::ConstantFP::get(VMContext, F);
3393 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3397 value = Builder.CreateCall(
3400 value,
"incdec.conv");
3402 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3407 }
else if (
type->isFixedPointType()) {
3414 Info.Opcode = isInc ? BO_Add : BO_Sub;
3416 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3419 if (
type->isSignedFixedPointType()) {
3420 Info.Opcode = isInc ? BO_Sub : BO_Add;
3421 Info.RHS = Builder.CreateNeg(Info.RHS);
3426 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3428 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3429 value = EmitFixedPointBinOp(Info);
3433 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3436 if (!isInc) size = -size;
3437 llvm::Value *sizeValue =
3438 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3441 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3444 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3446 value = Builder.CreateBitCast(value, input->getType());
3450 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3455 llvm::Value *
success = Pair.second;
3456 atomicPHI->addIncoming(old, curBlock);
3457 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3458 Builder.SetInsertPoint(contBB);
3459 return isPre ? value : input;
3463 if (LV.isBitField()) {
3473 return isPre ? value : input;
3477Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3478 QualType PromotionType) {
3479 QualType promotionTy = PromotionType.
isNull()
3482 Value *result = VisitPlus(E, promotionTy);
3483 if (result && !promotionTy.
isNull())
3484 result = EmitUnPromotedValue(result, E->
getType());
3488Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3489 QualType PromotionType) {
3491 TestAndClearIgnoreResultAssign();
3492 if (!PromotionType.
isNull())
3497Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3498 QualType PromotionType) {
3499 QualType promotionTy = PromotionType.
isNull()
3502 Value *result = VisitMinus(E, promotionTy);
3503 if (result && !promotionTy.
isNull())
3504 result = EmitUnPromotedValue(result, E->
getType());
3508Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3509 QualType PromotionType) {
3510 TestAndClearIgnoreResultAssign();
3512 if (!PromotionType.
isNull())
3518 if (Op->
getType()->isFPOrFPVectorTy())
3519 return Builder.CreateFNeg(Op,
"fneg");
3524 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3526 BinOp.Opcode = BO_Sub;
3529 return EmitSub(BinOp);
3532Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3533 TestAndClearIgnoreResultAssign();
3535 return Builder.CreateNot(Op,
"not");
3538Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3542 VectorKind::Generic) {
3546 if (Oper->
getType()->isFPOrFPVectorTy()) {
3547 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3549 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3551 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3552 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3561 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3564 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3567Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3569 Expr::EvalResult EVResult;
3572 return Builder.getInt(
Value);
3577 llvm::Type* ResultType = ConvertType(E->
getType());
3578 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3580 for (
unsigned i = 0; i != n; ++i) {
3582 llvm::Value *Offset =
nullptr;
3589 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3596 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3600 Offset = Builder.CreateMul(Idx, ElemSize);
3605 FieldDecl *MemberDecl = ON.
getField();
3613 FieldEnd = RD->field_end();
3614 Field != FieldEnd; ++Field, ++i) {
3615 if (*Field == MemberDecl)
3618 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3623 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3626 CurrentType = MemberDecl->
getType();
3631 llvm_unreachable(
"dependent __builtin_offsetof");
3648 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3660ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3661 const UnaryExprOrTypeTraitExpr *E) {
3664 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3665 if (
const VariableArrayType *VAT =
3670 bool EvaluateExtent =
true;
3671 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3673 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3675 if (EvaluateExtent) {
3686 if (Kind == UETT_CountOf)
3695 if (!eltSize.
isOne())
3698 return VlaSize.NumElts;
3701 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3707 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3708 }
else if (E->
getKind() == UETT_VectorElements) {
3710 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3718Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3719 QualType PromotionType) {
3720 QualType promotionTy = PromotionType.
isNull()
3723 Value *result = VisitReal(E, promotionTy);
3724 if (result && !promotionTy.
isNull())
3725 result = EmitUnPromotedValue(result, E->
getType());
3729Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3730 QualType PromotionType) {
3737 if (!PromotionType.
isNull()) {
3739 Op, IgnoreResultAssign,
true);
3754 if (!PromotionType.
isNull())
3759Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3760 QualType PromotionType) {
3761 QualType promotionTy = PromotionType.
isNull()
3764 Value *result = VisitImag(E, promotionTy);
3765 if (result && !promotionTy.
isNull())
3766 result = EmitUnPromotedValue(result, E->
getType());
3770Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3771 QualType PromotionType) {
3778 if (!PromotionType.
isNull()) {
3780 Op,
true, IgnoreResultAssign);
3784 return result.second
3800 else if (!PromotionType.
isNull())
3804 if (!PromotionType.
isNull())
3805 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3806 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3813Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3814 QualType PromotionType) {
3815 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3818Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3819 QualType ExprType) {
3820 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3823Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3825 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3827#define HANDLE_BINOP(OP) \
3829 return Emit##OP(EmitBinOps(BO, PromotionType));
3838 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3841 return VisitImag(UO, PromotionType);
3843 return VisitReal(UO, PromotionType);
3845 return VisitMinus(UO, PromotionType);
3847 return VisitPlus(UO, PromotionType);
3852 auto result = Visit(
const_cast<Expr *
>(E));
3854 if (!PromotionType.
isNull())
3855 return EmitPromotedValue(result, PromotionType);
3857 return EmitUnPromotedValue(result, E->
getType());
3862BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
3863 QualType PromotionType) {
3864 TestAndClearIgnoreResultAssign();
3868 if (!PromotionType.
isNull())
3869 Result.Ty = PromotionType;
3878LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3879 const CompoundAssignOperator *E,
3880 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3891 QualType PromotionTypeCR;
3893 if (PromotionTypeCR.
isNull())
3896 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
3897 if (!PromotionTypeRHS.
isNull())
3900 OpInfo.RHS = Visit(E->
getRHS());
3901 OpInfo.Ty = PromotionTypeCR;
3908 llvm::PHINode *atomicPHI =
nullptr;
3909 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
3910 QualType
type = atomicTy->getValueType();
3911 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3912 !(
type->isUnsignedIntegerType() &&
3913 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3915 LangOptions::SOB_Trapping) {
3916 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3917 llvm::Instruction::BinaryOps Op;
3918 switch (OpInfo.Opcode) {
3920 case BO_MulAssign:
case BO_DivAssign:
3926 AtomicOp = llvm::AtomicRMWInst::Add;
3927 Op = llvm::Instruction::Add;
3930 AtomicOp = llvm::AtomicRMWInst::Sub;
3931 Op = llvm::Instruction::Sub;
3934 AtomicOp = llvm::AtomicRMWInst::And;
3935 Op = llvm::Instruction::And;
3938 AtomicOp = llvm::AtomicRMWInst::Xor;
3939 Op = llvm::Instruction::Xor;
3942 AtomicOp = llvm::AtomicRMWInst::Or;
3943 Op = llvm::Instruction::Or;
3946 llvm_unreachable(
"Invalid compound assignment type");
3948 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3950 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3954 llvm::AtomicRMWInst *OldVal =
3959 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3965 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3967 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3969 Builder.CreateBr(opBB);
3970 Builder.SetInsertPoint(opBB);
3971 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3972 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3973 OpInfo.LHS = atomicPHI;
3976 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3978 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3980 if (!PromotionTypeLHS.
isNull())
3981 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3984 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3995 if (LHSLV.isBitField()) {
3997 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
3999 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4000 ScalarConversionOpts(CGF.
SanOpts));
4003 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4007 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4008 llvm::Value *
success = Pair.second;
4009 atomicPHI->addIncoming(old, curBlock);
4010 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4011 Builder.SetInsertPoint(contBB);
4019 if (LHSLV.isBitField()) {
4035Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4036 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4037 bool Ignore = TestAndClearIgnoreResultAssign();
4038 Value *RHS =
nullptr;
4039 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4050 if (!LHS.isVolatileQualified())
4054 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4057void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4058 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4059 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4062 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4063 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4064 SanitizerKind::SO_IntegerDivideByZero));
4068 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4069 Ops.Ty->hasSignedIntegerRepresentation() &&
4071 Ops.mayHaveIntegerOverflow()) {
4074 llvm::Value *IntMin =
4075 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4076 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4078 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4079 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4080 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4082 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4085 if (Checks.size() > 0)
4086 EmitBinOpCheck(Checks, Ops);
4089Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4091 SanitizerDebugLocation SanScope(&CGF,
4092 {SanitizerKind::SO_IntegerDivideByZero,
4093 SanitizerKind::SO_SignedIntegerOverflow,
4094 SanitizerKind::SO_FloatDivideByZero},
4095 SanitizerHandler::DivremOverflow);
4096 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4097 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4098 Ops.Ty->isIntegerType() &&
4099 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4100 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4101 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4102 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4103 Ops.Ty->isRealFloatingType() &&
4104 Ops.mayHaveFloatDivisionByZero()) {
4105 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4106 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4108 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4112 if (Ops.Ty->isConstantMatrixType()) {
4113 llvm::MatrixBuilder MB(Builder);
4120 "first operand must be a matrix");
4122 "second operand must be an arithmetic type");
4123 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4124 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4125 Ops.Ty->hasUnsignedIntegerRepresentation());
4128 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4130 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4131 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4135 else if (Ops.isFixedPointOp())
4136 return EmitFixedPointBinOp(Ops);
4137 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4138 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4140 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4143Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4145 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4146 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4147 Ops.Ty->isIntegerType() &&
4148 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4149 SanitizerDebugLocation SanScope(&CGF,
4150 {SanitizerKind::SO_IntegerDivideByZero,
4151 SanitizerKind::SO_SignedIntegerOverflow},
4152 SanitizerHandler::DivremOverflow);
4153 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4154 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4157 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4158 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4160 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4161 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4163 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4166Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4171 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4172 switch (Ops.Opcode) {
4176 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4177 llvm::Intrinsic::uadd_with_overflow;
4178 OverflowKind = SanitizerHandler::AddOverflow;
4183 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4184 llvm::Intrinsic::usub_with_overflow;
4185 OverflowKind = SanitizerHandler::SubOverflow;
4190 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4191 llvm::Intrinsic::umul_with_overflow;
4192 OverflowKind = SanitizerHandler::MulOverflow;
4195 llvm_unreachable(
"Unsupported operation for overflow detection");
4201 SanitizerDebugLocation SanScope(&CGF,
4202 {SanitizerKind::SO_SignedIntegerOverflow,
4203 SanitizerKind::SO_UnsignedIntegerOverflow},
4209 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4210 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4211 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4214 const std::string *handlerName =
4216 if (handlerName->empty()) {
4219 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4220 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
4222 isSigned ? SanitizerKind::SO_SignedIntegerOverflow
4223 : SanitizerKind::SO_UnsignedIntegerOverflow;
4224 EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops);
4226 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4231 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4232 llvm::BasicBlock *continueBB =
4236 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4240 Builder.SetInsertPoint(overflowBB);
4243 llvm::Type *Int8Ty = CGF.
Int8Ty;
4244 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4245 llvm::FunctionType *handlerTy =
4246 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4247 llvm::FunctionCallee handler =
4252 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4253 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4257 llvm::Value *handlerArgs[] = {
4260 Builder.getInt8(OpID),
4263 llvm::Value *handlerResult =
4267 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4268 Builder.CreateBr(continueBB);
4270 Builder.SetInsertPoint(continueBB);
4271 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4272 phi->addIncoming(result, initialBB);
4273 phi->addIncoming(handlerResult, overflowBB);
4282 bool isSubtraction) {
4287 Value *pointer = op.LHS;
4288 Expr *pointerOperand =
expr->getLHS();
4290 Expr *indexOperand =
expr->getRHS();
4293 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4294 std::swap(pointer,
index);
4295 std::swap(pointerOperand, indexOperand);
4299 index, isSubtraction);
4305 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4309 auto &DL =
CGM.getDataLayout();
4332 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4334 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4335 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4336 PtrTy->getPointerAddressSpace()))
4339 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4340 auto CheckHandler = SanitizerHandler::PointerOverflow;
4342 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4344 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4345 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4347 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4348 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4353 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4364 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4374 llvm::Value *objectSize =
4380 return Builder.CreateBitCast(result, pointer->getType());
4385 getContext().getAsVariableArrayType(elementType)) {
4387 llvm::Value *numElements =
getVLASize(vla).NumElts;
4396 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4416 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4429 bool negMul,
bool negAdd) {
4430 Value *MulOp0 = MulOp->getOperand(0);
4431 Value *MulOp1 = MulOp->getOperand(1);
4433 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4435 Addend = Builder.CreateFNeg(Addend,
"neg");
4437 Value *FMulAdd =
nullptr;
4438 if (Builder.getIsFPConstrained()) {
4440 "Only constrained operation should be created when Builder is in FP "
4441 "constrained mode");
4442 FMulAdd = Builder.CreateConstrainedFPCall(
4443 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4445 {MulOp0, MulOp1, Addend});
4447 FMulAdd = Builder.CreateCall(
4449 {MulOp0, MulOp1, Addend});
4451 MulOp->eraseFromParent();
4466 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4467 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4468 "Only fadd/fsub can be the root of an fmuladd.");
4471 if (!op.FPFeatures.allowFPContractWithinStatement())
4474 Value *LHS = op.LHS;
4475 Value *RHS = op.RHS;
4479 bool NegLHS =
false;
4480 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4481 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4482 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4483 LHS = LHSUnOp->getOperand(0);
4488 bool NegRHS =
false;
4489 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4490 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4491 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4492 RHS = RHSUnOp->getOperand(0);
4500 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4501 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4502 (LHSBinOp->use_empty() || NegLHS)) {
4506 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4509 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4510 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4511 (RHSBinOp->use_empty() || NegRHS)) {
4515 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4519 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4520 if (LHSBinOp->getIntrinsicID() ==
4521 llvm::Intrinsic::experimental_constrained_fmul &&
4522 (LHSBinOp->use_empty() || NegLHS)) {
4526 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4529 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4530 if (RHSBinOp->getIntrinsicID() ==
4531 llvm::Intrinsic::experimental_constrained_fmul &&
4532 (RHSBinOp->use_empty() || NegRHS)) {
4536 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4543Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4544 if (op.LHS->getType()->isPointerTy() ||
4545 op.RHS->getType()->isPointerTy())
4548 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4549 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4550 case LangOptions::SOB_Defined:
4551 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4552 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4554 case LangOptions::SOB_Undefined:
4555 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4556 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4558 case LangOptions::SOB_Trapping:
4559 if (CanElideOverflowCheck(CGF.
getContext(), op))
4560 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4561 return EmitOverflowCheckedBinOp(op);
4566 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4567 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4573 if (op.Ty->isConstantMatrixType()) {
4574 llvm::MatrixBuilder MB(Builder);
4575 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4576 return MB.CreateAdd(op.LHS, op.RHS);
4579 if (op.Ty->isUnsignedIntegerType() &&
4580 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4581 !CanElideOverflowCheck(CGF.
getContext(), op))
4582 return EmitOverflowCheckedBinOp(op);
4584 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4585 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4586 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4589 if (op.isFixedPointOp())
4590 return EmitFixedPointBinOp(op);
4592 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4597Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4599 using llvm::ConstantInt;
4605 QualType ResultTy = op.Ty;
4606 QualType LHSTy, RHSTy;
4607 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4608 RHSTy = BinOp->getRHS()->getType();
4609 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4614 LHSTy = CAO->getComputationLHSType();
4615 ResultTy = CAO->getComputationResultType();
4617 LHSTy = BinOp->getLHS()->getType();
4618 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4619 LHSTy = UnOp->getSubExpr()->getType();
4620 RHSTy = UnOp->getSubExpr()->getType();
4623 Value *LHS = op.LHS;
4624 Value *RHS = op.RHS;
4629 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4633 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4634 switch (op.Opcode) {
4637 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4641 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4645 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4649 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4653 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4657 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4660 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4662 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4664 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4666 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4671 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4673 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4677 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4690 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4696 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4701Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4703 if (!op.LHS->getType()->isPointerTy()) {
4704 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4705 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4706 case LangOptions::SOB_Defined:
4707 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4708 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4710 case LangOptions::SOB_Undefined:
4711 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4712 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4714 case LangOptions::SOB_Trapping:
4715 if (CanElideOverflowCheck(CGF.
getContext(), op))
4716 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4717 return EmitOverflowCheckedBinOp(op);
4722 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4723 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4729 if (op.Ty->isConstantMatrixType()) {
4730 llvm::MatrixBuilder MB(Builder);
4731 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4732 return MB.CreateSub(op.LHS, op.RHS);
4735 if (op.Ty->isUnsignedIntegerType() &&
4736 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4737 !CanElideOverflowCheck(CGF.
getContext(), op))
4738 return EmitOverflowCheckedBinOp(op);
4740 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4741 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4742 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4745 if (op.isFixedPointOp())
4746 return EmitFixedPointBinOp(op);
4748 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4753 if (!op.RHS->getType()->isPointerTy())
4760 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4762 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4763 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4767 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4769 llvm::Value *divisor =
nullptr;
4772 if (
const VariableArrayType *vla
4775 elementType = VlaSize.Type;
4776 divisor = VlaSize.NumElts;
4780 if (!eltSize.
isOne())
4787 CharUnits elementSize;
4796 if (elementSize.
isOne())
4805 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4808Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4810 llvm::IntegerType *Ty;
4811 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4819 llvm::Type *RHSTy = RHS->
getType();
4820 llvm::APInt RHSMax =
4821 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4822 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4823 if (RHSMax.ult(Ty->getBitWidth()))
4824 return llvm::ConstantInt::get(RHSTy, RHSMax);
4825 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4829 const Twine &Name) {
4830 llvm::IntegerType *Ty;
4831 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4836 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4837 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4839 return Builder.CreateURem(
4840 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4843Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4845 if (Ops.isFixedPointOp())
4846 return EmitFixedPointBinOp(Ops);
4850 Value *RHS = Ops.RHS;
4851 if (Ops.LHS->getType() != RHS->
getType())
4852 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4854 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4855 Ops.Ty->hasSignedIntegerRepresentation() &&
4858 bool SanitizeUnsignedBase =
4859 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4860 Ops.Ty->hasUnsignedIntegerRepresentation();
4861 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4862 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4865 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4866 else if ((SanitizeBase || SanitizeExponent) &&
4868 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
4869 if (SanitizeSignedBase)
4870 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
4871 if (SanitizeUnsignedBase)
4872 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
4873 if (SanitizeExponent)
4874 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
4876 SanitizerDebugLocation SanScope(&CGF, Ordinals,
4877 SanitizerHandler::ShiftOutOfBounds);
4878 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
4879 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4880 llvm::Value *WidthMinusOne =
4881 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4882 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4884 if (SanitizeExponent) {
4886 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
4893 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4896 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4897 llvm::Value *PromotedWidthMinusOne =
4898 (RHS == Ops.RHS) ? WidthMinusOne
4899 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4901 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4902 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4911 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4912 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4914 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4915 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
4917 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4918 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4919 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4920 Checks.push_back(std::make_pair(
4921 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
4922 : SanitizerKind::SO_UnsignedShiftBase));
4925 assert(!Checks.empty());
4926 EmitBinOpCheck(Checks, Ops);
4929 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4932Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4934 if (Ops.isFixedPointOp())
4935 return EmitFixedPointBinOp(Ops);
4939 Value *RHS = Ops.RHS;
4940 if (Ops.LHS->getType() != RHS->
getType())
4941 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4945 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4946 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4948 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
4949 SanitizerHandler::ShiftOutOfBounds);
4950 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4951 llvm::Value *
Valid = Builder.CreateICmpULE(
4952 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4953 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
4956 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4957 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4958 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4966 default: llvm_unreachable(
"unexpected element type");
4967 case BuiltinType::Char_U:
4968 case BuiltinType::UChar:
4969 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4970 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4971 case BuiltinType::Char_S:
4972 case BuiltinType::SChar:
4973 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4974 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4975 case BuiltinType::UShort:
4976 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4977 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4978 case BuiltinType::Short:
4979 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4980 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4981 case BuiltinType::UInt:
4982 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4983 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4984 case BuiltinType::Int:
4985 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4986 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4987 case BuiltinType::ULong:
4988 case BuiltinType::ULongLong:
4989 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4990 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4991 case BuiltinType::Long:
4992 case BuiltinType::LongLong:
4993 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4994 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4995 case BuiltinType::Float:
4996 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4997 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4998 case BuiltinType::Double:
4999 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5000 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5001 case BuiltinType::UInt128:
5002 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5003 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5004 case BuiltinType::Int128:
5005 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5006 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5010Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5011 llvm::CmpInst::Predicate UICmpOpc,
5012 llvm::CmpInst::Predicate SICmpOpc,
5013 llvm::CmpInst::Predicate FCmpOpc,
5015 TestAndClearIgnoreResultAssign();
5019 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5025 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5027 BinOpInfo BOInfo = EmitBinOps(E);
5028 Value *LHS = BOInfo.LHS;
5029 Value *RHS = BOInfo.RHS;
5035 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5037 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5040 Value *FirstVecArg = LHS,
5041 *SecondVecArg = RHS;
5043 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5047 default: llvm_unreachable(
"is not a comparison operation");
5059 std::swap(FirstVecArg, SecondVecArg);
5066 if (ElementKind == BuiltinType::Float) {
5068 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5069 std::swap(FirstVecArg, SecondVecArg);
5077 if (ElementKind == BuiltinType::Float) {
5079 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5084 std::swap(FirstVecArg, SecondVecArg);
5089 Value *CR6Param = Builder.getInt32(CR6);
5091 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5099 if (ResultTy->getBitWidth() > 1 &&
5101 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5106 if (BOInfo.isFixedPointOp()) {
5107 Result = EmitFixedPointBinOp(BOInfo);
5108 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5109 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5111 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5113 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5115 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5130 LHS = Builder.CreateStripInvariantGroup(LHS);
5132 RHS = Builder.CreateStripInvariantGroup(RHS);
5135 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5141 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5147 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5149 CETy = CTy->getElementType();
5151 LHS.first = Visit(E->
getLHS());
5152 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5155 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5158 CTy->getElementType()) &&
5159 "The element types must always match.");
5162 RHS.first = Visit(E->
getRHS());
5163 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5165 "The element types must always match.");
5168 Value *ResultR, *ResultI;
5172 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5173 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5177 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5178 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5182 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5185 "Complex comparison other than == or != ?");
5186 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5198 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5199 CastKind Kind = ICE->getCastKind();
5200 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5201 *SrcType = ICE->getSubExpr()->getType();
5214 bool Ignore = TestAndClearIgnoreResultAssign();
5248 RHS = Visit(E->
getRHS());
5264 RHS = Visit(E->
getRHS());
5304 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5307Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5315 if (LHS->
getType()->isFPOrFPVectorTy()) {
5316 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5318 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5319 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5321 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5322 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5324 Value *
And = Builder.CreateAnd(LHS, RHS);
5325 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5329 llvm::Type *ResTy = ConvertType(E->
getType());
5350 if (InstrumentRegions &&
5355 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
5369 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5375 return llvm::Constant::getNullValue(ResTy);
5388 CodeGenFunction::ConditionalEvaluation eval(CGF);
5397 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5399 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5401 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5410 RHSBlock = Builder.GetInsertBlock();
5415 if (InstrumentRegions &&
5419 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5423 PN->addIncoming(RHSCond, RHSBlockCnt);
5433 PN->addIncoming(RHSCond, RHSBlock);
5443 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5447 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5450Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5458 if (LHS->
getType()->isFPOrFPVectorTy()) {
5459 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5461 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5462 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5464 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5465 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5467 Value *
Or = Builder.CreateOr(LHS, RHS);
5468 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5472 llvm::Type *ResTy = ConvertType(E->
getType());
5493 if (InstrumentRegions &&
5498 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5512 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5518 return llvm::ConstantInt::get(ResTy, 1);
5531 CodeGenFunction::ConditionalEvaluation eval(CGF);
5541 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5543 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5545 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5557 RHSBlock = Builder.GetInsertBlock();
5562 if (InstrumentRegions &&
5566 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5570 PN->addIncoming(RHSCond, RHSBlockCnt);
5576 PN->addIncoming(RHSCond, RHSBlock);
5584 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5587Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5590 return Visit(E->
getRHS());
5615Value *ScalarExprEmitter::
5616VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5617 TestAndClearIgnoreResultAssign();
5620 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5622 Expr *condExpr = E->
getCond();
5630 Expr *live = lhsExpr, *dead = rhsExpr;
5631 if (!CondExprBool) std::swap(live, dead);
5662 llvm::Value *LHS = Visit(lhsExpr);
5663 llvm::Value *RHS = Visit(rhsExpr);
5665 llvm::Type *condType = ConvertType(condExpr->
getType());
5668 unsigned numElem = vecTy->getNumElements();
5669 llvm::Type *elemType = vecTy->getElementType();
5671 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5672 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5673 llvm::Value *tmp = Builder.CreateSExt(
5674 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5675 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5678 llvm::Value *RHSTmp = RHS;
5679 llvm::Value *LHSTmp = LHS;
5680 bool wasCast =
false;
5682 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5683 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5684 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5688 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5689 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5690 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5692 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5702 llvm::Value *LHS = Visit(lhsExpr);
5703 llvm::Value *RHS = Visit(rhsExpr);
5705 llvm::Type *CondType = ConvertType(condExpr->
getType());
5708 if (VecTy->getElementType()->isIntegerTy(1))
5709 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5712 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5714 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5716 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5717 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5726 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5735 llvm::Value *LHS = Visit(lhsExpr);
5736 llvm::Value *RHS = Visit(rhsExpr);
5739 assert(!RHS &&
"LHS and RHS types must match");
5742 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5753 CodeGenFunction::ConditionalEvaluation eval(CGF);
5771 Value *LHS = Visit(lhsExpr);
5774 LHSBlock = Builder.GetInsertBlock();
5775 Builder.CreateBr(ContBlock);
5789 Value *RHS = Visit(rhsExpr);
5792 RHSBlock = Builder.GetInsertBlock();
5802 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5803 PN->addIncoming(LHS, LHSBlock);
5804 PN->addIncoming(RHS, RHSBlock);
5814Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
5818Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
5820 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
5825Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5831 Value *Src,
unsigned NumElementsDst) {
5832 static constexpr int Mask[] = {0, 1, 2, -1};
5833 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5853 const llvm::DataLayout &DL,
5854 Value *Src, llvm::Type *DstTy,
5855 StringRef Name =
"") {
5859 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5860 return Builder.CreateBitCast(Src, DstTy, Name);
5863 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5864 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5867 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5869 if (!DstTy->isIntegerTy())
5870 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5872 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5876 if (!SrcTy->isIntegerTy())
5877 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5879 return Builder.CreateIntToPtr(Src, DstTy, Name);
5882Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
5884 llvm::Type *DstTy = ConvertType(E->
getType());
5886 llvm::Type *SrcTy = Src->
getType();
5887 unsigned NumElementsSrc =
5891 unsigned NumElementsDst =
5902 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5907 Src->setName(
"astype");
5914 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5915 auto *Vec4Ty = llvm::FixedVectorType::get(
5921 Src->setName(
"astype");
5926 Src, DstTy,
"astype");
5929Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
5941 "Invalid scalar expression to emit");
5943 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5944 .Visit(
const_cast<Expr *
>(E));
5953 "Invalid scalar expression to emit");
5954 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
5964 "Invalid complex -> scalar conversion");
5965 return ScalarExprEmitter(*
this)
5966 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
5973 if (!PromotionType.
isNull())
5974 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5976 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
5982 bool isInc,
bool isPre) {
5983 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
5993 llvm::Type *BaseTy =
6009 ScalarExprEmitter Scalar(*
this);
6012#define COMPOUND_OP(Op) \
6013 case BO_##Op##Assign: \
6014 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6051 llvm_unreachable(
"Not valid compound assignment operators");
6054 llvm_unreachable(
"Unhandled compound assignment operator");
6069 llvm::LLVMContext &VMContext,
6075 llvm::Value *TotalOffset =
nullptr;
6081 Value *BasePtr_int =
6082 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6084 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6085 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6086 return {TotalOffset, Builder.getFalse()};
6090 assert(GEP->getPointerOperand() == BasePtr &&
6091 "BasePtr must be the base of the GEP.");
6092 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6094 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6097 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6098 auto *SAddIntrinsic =
6099 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6100 auto *SMulIntrinsic =
6101 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6104 llvm::Value *OffsetOverflows = Builder.getFalse();
6108 llvm::Value *RHS) -> llvm::Value * {
6109 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6112 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6113 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6115 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6118 OffsetOverflows = Builder.getTrue();
6119 return llvm::ConstantInt::get(VMContext, N);
6124 auto *ResultAndOverflow = Builder.CreateCall(
6125 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6126 OffsetOverflows = Builder.CreateOr(
6127 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6128 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6132 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6133 GTI != GTE; ++GTI) {
6134 llvm::Value *LocalOffset;
6135 auto *Index = GTI.getOperand();
6137 if (
auto *STy = GTI.getStructTypeOrNull()) {
6141 LocalOffset = llvm::ConstantInt::get(
6142 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6147 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6148 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6149 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6154 if (!TotalOffset || TotalOffset ==
Zero)
6155 TotalOffset = LocalOffset;
6157 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6160 return {TotalOffset, OffsetOverflows};
6165 ArrayRef<Value *> IdxList,
6166 bool SignedIndices,
bool IsSubtraction,
6167 SourceLocation Loc,
const Twine &Name) {
6168 llvm::Type *PtrTy = Ptr->
getType();
6170 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6171 if (!SignedIndices && !IsSubtraction)
6172 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6174 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6177 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6181 bool PerformNullCheck = !NullPointerIsDefined(
6182 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6185 bool PerformOverflowCheck =
6188 if (!(PerformNullCheck || PerformOverflowCheck))
6191 const auto &DL = CGM.getDataLayout();
6193 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6194 auto CheckHandler = SanitizerHandler::PointerOverflow;
6195 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6196 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6198 GEPOffsetAndOverflow EvaluatedGEP =
6203 "If the offset got constant-folded, we don't expect that there was an "
6206 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6214 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6215 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6217 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6221 if (PerformNullCheck) {
6229 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6230 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6231 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6232 Checks.emplace_back(
Valid, CheckOrdinal);
6235 if (PerformOverflowCheck) {
6240 llvm::Value *ValidGEP;
6241 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6242 if (SignedIndices) {
6248 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6249 auto *PosOrZeroOffset =
6251 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6253 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6254 }
else if (!IsSubtraction) {
6259 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6265 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6267 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6268 Checks.emplace_back(ValidGEP, CheckOrdinal);
6271 assert(!Checks.empty() &&
"Should have produced some checks.");
6273 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6275 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6276 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6282 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6283 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6284 const Twine &Name) {
6285 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6286 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6287 if (!SignedIndices && !IsSubtraction)
6288 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6290 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6294 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6295 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6296 elementType, Align);
Defines the clang::ASTContext interface.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
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 isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
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 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 isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
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 BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *e, CIRGenFunction &cgf)
Return true if the specified expression is cheap enough and side-effect-free enough to evaluate uncon...
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
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.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
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
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.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
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.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
LabelDecl * getLabel() const
uint64_t getValue() const
QualType getElementType() const
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BinaryOperatorKind Opcode
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.
Expr * getExpr()
Get the initialization expression that will be used.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::LoadInst * CreateLoad(Address Addr, 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.
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
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 * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
SanitizerSet SanOpts
Sanitizers enabled for this function.
RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
const CastExpr * CurCast
If a cast expression is being visited, this holds the current cast's expression.
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitPointerAuthQualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType ValueType, Address StorageAddress, bool IsKnownNonNull)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
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.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
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.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
const LangOptions & getLangOpts() const
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
bool isPointerKnownNonNull(const Expr *E)
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
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.
llvm::Value * EmitPointerAuthUnqualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType PointerType, Address StorageAddress, bool IsKnownNonNull)
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
Emit a compare-and-exchange op for atomic type.
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.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
@ 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.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
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.
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
const TargetInfo & getTarget() const
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
CGDebugInfo * getDebugInfo()
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
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 * 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...
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
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 * EmitPointerArithmetic(const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer, Expr *indexOperand, llvm::Value *index, bool isSubtraction)
Emit pointer + index arithmetic.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitAtomicExpr(AtomicExpr *E)
void markStmtMaybeUsed(const Stmt *S)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
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...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
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 * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
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...
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
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...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
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.
TrapReasonBuilder BuildTrapReason(unsigned DiagID, TrapReason &TR)
Helper function to construct a TrapReasonBuilder.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
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.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
const Qualifiers & getQuals() const
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)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
const Expr * getDefaultExpr() const
ChildElementIter< false > begin()
size_t getDataElementCount() const
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,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
unsigned getNumInits() const
bool hadArrayRangeDesignator() const
const Expr * getInit(unsigned Init) const
@ 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 matrix type, as defined in the Matrix Types clang extensions.
VersionTuple getVersion() const
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
SourceLocation getExprLoc() const LLVM_READONLY
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
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.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
DynTypedNodeList getParents(const NodeT &Node)
Returns the parents of the given node (within the traversal scope).
Pointer-authentication qualifiers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
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.
specific_decl_iterator< FieldDecl > field_iterator
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
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.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getReplacement() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
bool isBooleanType() const
bool isSignableType(const ASTContext &Ctx) 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 ...
CXXRecordDecl * castAsCXXRecordDecl() const
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.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool 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 * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
WhileStmt - This represents a 'while' stmt.
Defines the clang::TargetInfo interface.
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 AstTypeMatcher< PointerType > pointerType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool LE(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.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ Result
The result type of a method or function.
const FunctionProtoType * T
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
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()
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.