36#include "llvm/ADT/APFixedPoint.h"
37#include "llvm/ADT/ScopeExit.h"
38#include "llvm/IR/Argument.h"
39#include "llvm/IR/CFG.h"
40#include "llvm/IR/Constants.h"
41#include "llvm/IR/DataLayout.h"
42#include "llvm/IR/DerivedTypes.h"
43#include "llvm/IR/FixedPointBuilder.h"
44#include "llvm/IR/Function.h"
45#include "llvm/IR/GEPNoWrapFlags.h"
46#include "llvm/IR/GetElementPtrTypeIterator.h"
47#include "llvm/IR/GlobalVariable.h"
48#include "llvm/IR/Intrinsics.h"
49#include "llvm/IR/IntrinsicsPowerPC.h"
50#include "llvm/IR/MatrixBuilder.h"
51#include "llvm/IR/Module.h"
52#include "llvm/Support/TypeSize.h"
75bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
80 const auto &LHSAP = LHS->getValue();
81 const auto &RHSAP = RHS->getValue();
82 if (Opcode == BO_Add) {
84 : LHSAP.uadd_ov(RHSAP, Overflow);
85 }
else if (Opcode == BO_Sub) {
87 : LHSAP.usub_ov(RHSAP, Overflow);
88 }
else if (Opcode == BO_Mul) {
90 : LHSAP.umul_ov(RHSAP, Overflow);
91 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
92 if (
Signed && !RHS->isZero())
93 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
105 FPOptions FPFeatures;
109 bool mayHaveIntegerOverflow()
const {
111 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
112 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
113 if (!LHSCI || !RHSCI)
117 return ::mayHaveIntegerOverflow(
122 bool isDivremOp()
const {
128 bool mayHaveIntegerDivisionByZero()
const {
130 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
136 bool mayHaveFloatDivisionByZero()
const {
138 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
139 return CFP->isZero();
146 bool isFixedPointOp()
const {
149 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
150 QualType LHSType = BinOp->getLHS()->getType();
151 QualType RHSType = BinOp->getRHS()->getType();
154 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
155 return UnOp->getSubExpr()->getType()->isFixedPointType();
160 bool rhsHasSignedIntegerRepresentation()
const {
161 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
162 QualType RHSType = BinOp->getRHS()->getType();
169static bool MustVisitNullValue(
const Expr *E) {
192static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
202 const OverflowBehaviorType *OBT = Ty->
getAs<OverflowBehaviorType>();
207 switch (OBT->getBehaviorKind()) {
208 case OverflowBehaviorType::OverflowBehaviorKind::Wrap:
210 case OverflowBehaviorType::OverflowBehaviorKind::Trap:
213 llvm_unreachable(
"Unknown OverflowBehaviorKind");
220 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
228 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
232static bool CanElideOverflowCheck(
ASTContext &Ctx,
const BinOpInfo &Op) {
234 "Expected a unary or binary operator");
238 if (!Op.mayHaveIntegerOverflow())
245 const auto *BO = dyn_cast<BinaryOperator>(Op.E);
246 if (BO && BO->hasExcludedOverflowPattern())
249 if (Op.Ty.isWrapType())
251 if (Op.Ty.isTrapType())
254 if (Op.Ty->isSignedIntegerType() &&
260 if (Op.Ty->isUnsignedIntegerType() &&
285 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
291 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
292 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
296class ScalarExprEmitter
298 CodeGenFunction &CGF;
299 CGBuilderTy &Builder;
300 bool IgnoreResultAssign;
301 llvm::LLVMContext &VMContext;
304 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
305 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
306 VMContext(cgf.getLLVMContext()) {
313 bool TestAndClearIgnoreResultAssign() {
314 bool I = IgnoreResultAssign;
315 IgnoreResultAssign =
false;
319 llvm::Type *ConvertType(QualType T) {
return CGF.
ConvertType(T); }
320 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
326 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
327 const BinOpInfo &Info);
329 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
333 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
334 const AlignValueAttr *AVAttr =
nullptr;
335 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
336 const ValueDecl *VD = DRE->getDecl();
339 if (
const auto *TTy =
341 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
351 AVAttr = VD->
getAttr<AlignValueAttr>();
356 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
357 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
370 Value *EmitLoadOfLValue(
const Expr *E) {
374 EmitLValueAlignmentAssumption(E,
V);
380 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
384 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
385 Value *Src, QualType SrcType, QualType DstType,
386 llvm::Type *DstTy, SourceLocation Loc);
391 enum ImplicitConversionCheckKind :
unsigned char {
392 ICCK_IntegerTruncation = 0,
393 ICCK_UnsignedIntegerTruncation = 1,
394 ICCK_SignedIntegerTruncation = 2,
395 ICCK_IntegerSignChange = 3,
396 ICCK_SignedIntegerTruncationOrSignChange = 4,
401 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
402 QualType DstType, SourceLocation Loc,
403 bool OBTrapInvolved =
false);
408 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
409 QualType DstType, SourceLocation Loc,
410 bool OBTrapInvolved =
false);
414 struct ScalarConversionOpts {
415 bool TreatBooleanAsSigned;
416 bool EmitImplicitIntegerTruncationChecks;
417 bool EmitImplicitIntegerSignChangeChecks;
419 bool PatternExcluded;
421 ScalarConversionOpts()
422 : TreatBooleanAsSigned(
false),
423 EmitImplicitIntegerTruncationChecks(
false),
424 EmitImplicitIntegerSignChangeChecks(
false), PatternExcluded(
false) {}
426 ScalarConversionOpts(clang::SanitizerSet SanOpts)
427 : TreatBooleanAsSigned(
false),
428 EmitImplicitIntegerTruncationChecks(
429 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
430 EmitImplicitIntegerSignChangeChecks(
431 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)),
432 PatternExcluded(
false) {}
434 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
435 llvm::Type *SrcTy, llvm::Type *DstTy,
436 ScalarConversionOpts Opts);
438 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
440 ScalarConversionOpts Opts = ScalarConversionOpts());
444 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
450 QualType SrcTy, QualType DstTy,
454 Value *EmitNullValue(QualType Ty);
459 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
460 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
464 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
467 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
474 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
475 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
481 ZI->eraseFromParent();
486 return Builder.CreateIsNotNull(
V,
"tobool");
493 Value *Visit(Expr *E) {
494 ApplyDebugLocation DL(CGF, E);
495 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
498 Value *VisitStmt(Stmt *S) {
500 llvm_unreachable(
"Stmt can't have complex result type!");
502 Value *VisitExpr(Expr *S);
504 Value *VisitConstantExpr(ConstantExpr *E) {
510 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
525 Value *VisitParenExpr(ParenExpr *PE) {
528 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
531 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
532 return Visit(
GE->getResultExpr());
534 Value *VisitCoawaitExpr(CoawaitExpr *S) {
537 Value *VisitCoyieldExpr(CoyieldExpr *S) {
540 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
545 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
546 return Builder.getInt(E->
getValue());
548 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
549 return Builder.getInt(E->
getValue());
551 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
552 return llvm::ConstantFP::get(VMContext, E->
getValue());
554 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
557 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
560 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
561 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
563 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
564 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
566 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
570 return EmitNullValue(E->
getType());
572 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
573 return EmitNullValue(E->
getType());
575 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
576 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
577 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
579 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
582 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
586 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
590 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
591 Value *VisitEmbedExpr(EmbedExpr *E);
593 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
602 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
603 llvm_unreachable(
"Codegen for this isn't defined/implemented");
607 Value *VisitDeclRefExpr(DeclRefExpr *E) {
610 return EmitLoadOfLValue(E);
613 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
616 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
619 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
620 return EmitLoadOfLValue(E);
622 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
625 return EmitLoadOfLValue(E);
629 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
635 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
641 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
646 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
647 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
648 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
649 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
650 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
651 Value *VisitMemberExpr(MemberExpr *E);
652 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
653 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
654 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
660 return EmitLoadOfLValue(E);
663 Value *VisitInitListExpr(InitListExpr *E);
665 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
667 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
671 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
672 return EmitNullValue(E->
getType());
674 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
676 return VisitCastExpr(E);
680 Value *VisitCallExpr(
const CallExpr *E) {
682 return EmitLoadOfLValue(E);
686 EmitLValueAlignmentAssumption(E,
V);
690 Value *VisitStmtExpr(
const StmtExpr *E);
693 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
695 return EmitScalarPrePostIncDec(E, LV,
false,
false);
697 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
699 return EmitScalarPrePostIncDec(E, LV,
true,
false);
701 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
703 return EmitScalarPrePostIncDec(E, LV,
false,
true);
705 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
707 return EmitScalarPrePostIncDec(E, LV,
true,
true);
710 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
714 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
715 bool isInc,
bool isPre);
718 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
722 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
724 Value *VisitUnaryDeref(
const UnaryOperator *E) {
727 return EmitLoadOfLValue(E);
730 Value *VisitUnaryPlus(
const UnaryOperator *E,
731 QualType PromotionType = QualType());
732 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
733 Value *VisitUnaryMinus(
const UnaryOperator *E,
734 QualType PromotionType = QualType());
735 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
737 Value *VisitUnaryNot (
const UnaryOperator *E);
738 Value *VisitUnaryLNot (
const UnaryOperator *E);
739 Value *VisitUnaryReal(
const UnaryOperator *E,
740 QualType PromotionType = QualType());
741 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
742 Value *VisitUnaryImag(
const UnaryOperator *E,
743 QualType PromotionType = QualType());
744 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
745 Value *VisitUnaryExtension(
const UnaryOperator *E) {
750 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
751 return EmitLoadOfLValue(E);
753 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
761 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
762 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
765 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
766 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
769 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
773 Value *VisitExprWithCleanups(ExprWithCleanups *E);
774 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
777 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
782 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
784 return llvm::ConstantInt::get(ConvertType(E->
getType()),
787 return llvm::ConstantInt::get(ConvertType(E->
getType()),
791 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
799 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
800 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
803 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
804 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
807 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
817 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
818 return EmitNullValue(E->
getType());
821 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
826 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
827 return Builder.getInt1(E->
getValue());
831 Value *EmitMul(
const BinOpInfo &Ops) {
832 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
833 Ops.Ty->isUnsignedIntegerType()) {
834 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
836 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
837 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
838 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
839 case LangOptions::OB_Wrap:
840 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
841 case LangOptions::OB_SignedAndDefined:
843 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
845 case LangOptions::OB_Unset:
847 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
848 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
850 case LangOptions::OB_Trap:
851 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
852 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
853 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
854 return EmitOverflowCheckedBinOp(Ops);
858 if (Ops.Ty->isConstantMatrixType()) {
859 llvm::MatrixBuilder MB(Builder);
863 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
864 BO->getLHS()->getType().getCanonicalType());
865 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
866 BO->getRHS()->getType().getCanonicalType());
867 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
868 if (LHSMatTy && RHSMatTy)
869 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
870 LHSMatTy->getNumColumns(),
871 RHSMatTy->getNumColumns());
872 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
875 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
877 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
878 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
880 if (Ops.isFixedPointOp())
881 return EmitFixedPointBinOp(Ops);
882 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
886 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
889 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
890 llvm::Value *
Zero,
bool isDiv);
892 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
898 Value *EmitDiv(
const BinOpInfo &Ops);
899 Value *EmitRem(
const BinOpInfo &Ops);
900 Value *EmitAdd(
const BinOpInfo &Ops);
901 Value *EmitSub(
const BinOpInfo &Ops);
902 Value *EmitShl(
const BinOpInfo &Ops);
903 Value *EmitShr(
const BinOpInfo &Ops);
904 Value *EmitAnd(
const BinOpInfo &Ops) {
905 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
907 Value *EmitXor(
const BinOpInfo &Ops) {
908 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
910 Value *EmitOr (
const BinOpInfo &Ops) {
911 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
915 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
917 BinOpInfo EmitBinOps(
const BinaryOperator *E,
918 QualType PromotionTy = QualType());
920 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
921 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
922 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
924 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
925 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
928 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
929 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
931 QualType getPromotionType(QualType Ty) {
933 if (
auto *CT = Ty->
getAs<ComplexType>()) {
934 QualType ElementType = CT->getElementType();
940 if (
auto *VT = Ty->
getAs<VectorType>()) {
941 unsigned NumElements = VT->getNumElements();
951#define HANDLEBINOP(OP) \
952 Value *VisitBin##OP(const BinaryOperator *E) { \
953 QualType promotionTy = getPromotionType(E->getType()); \
954 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
955 if (result && !promotionTy.isNull()) \
956 result = EmitUnPromotedValue(result, E->getType()); \
959 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
960 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
961 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
977 llvm::CmpInst::Predicate SICmpOpc,
978 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
979#define VISITCOMP(CODE, UI, SI, FP, SIG) \
980 Value *VisitBin##CODE(const BinaryOperator *E) { \
981 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
982 llvm::FCmpInst::FP, SIG); }
983 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
997 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
998 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
1000 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1005 Value *VisitBlockExpr(
const BlockExpr *BE);
1006 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1007 Value *VisitChooseExpr(ChooseExpr *CE);
1008 Value *VisitVAArgExpr(VAArgExpr *VE);
1009 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1012 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1015 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1018 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1021 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1022 Value *VisitAtomicExpr(AtomicExpr *AE);
1023 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1036 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1039 return EmitFloatToBoolConversion(Src);
1041 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1045 if (SrcType == CGF.
getContext().AMDGPUFeaturePredicateTy)
1049 "Unknown scalar type to convert");
1052 return EmitIntToBoolConversion(Src);
1055 return EmitPointerToBoolConversion(Src, SrcType);
1058void ScalarExprEmitter::EmitFloatConversionCheck(
1059 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1060 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1061 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1065 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1066 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1067 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1068 using llvm::APFloat;
1071 llvm::Value *Check =
nullptr;
1072 const llvm::fltSemantics &SrcSema =
1082 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1083 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1084 APFloat::opOverflow)
1087 MinSrc = APFloat::getInf(SrcSema,
true);
1091 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1094 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1095 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1096 APFloat::opOverflow)
1099 MaxSrc = APFloat::getInf(SrcSema,
false);
1103 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1108 const llvm::fltSemantics &Sema =
1111 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1112 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1116 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1118 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1119 Check = Builder.CreateAnd(GE, LE);
1124 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1130static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1131 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1134 llvm::Type *SrcTy = Src->
getType();
1135 llvm::Type *DstTy = Dst->
getType();
1140 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1142 "non-integer llvm type");
1149 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1151 if (!SrcSigned && !DstSigned) {
1152 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1153 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1155 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1156 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1159 llvm::Value *Check =
nullptr;
1161 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1163 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1165 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1173void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1174 Value *Dst, QualType DstType,
1176 bool OBTrapInvolved) {
1177 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1187 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1188 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1190 if (SrcBits <= DstBits)
1193 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1200 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1201 (!SrcSigned && DstSigned))
1204 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1205 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1208 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1213 SanitizerDebugLocation SanScope(
1215 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1216 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1232 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1240 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1241 if (OBT->isWrapKind())
1244 if (ignoredBySanitizer && !OBTrapInvolved)
1247 llvm::Constant *StaticArgs[] = {
1250 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1251 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1253 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1260 llvm::Type *VTy =
V->getType();
1263 return llvm::ConstantInt::getFalse(VTy->getContext());
1265 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1266 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1267 llvm::Twine(Name) +
"." +
V->getName() +
1268 ".negativitycheck");
1273static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1274 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1277 llvm::Type *SrcTy = Src->
getType();
1278 llvm::Type *DstTy = Dst->
getType();
1281 "non-integer llvm type");
1287 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1288 unsigned DstBits = DstTy->getScalarSizeInBits();
1292 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1293 "either the widths should be different, or the signednesses.");
1296 llvm::Value *SrcIsNegative =
1299 llvm::Value *DstIsNegative =
1305 llvm::Value *Check =
nullptr;
1306 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1308 return std::make_pair(
1309 ScalarExprEmitter::ICCK_IntegerSignChange,
1310 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1313void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1314 Value *Dst, QualType DstType,
1316 bool OBTrapInvolved) {
1317 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1321 llvm::Type *SrcTy = Src->
getType();
1322 llvm::Type *DstTy = Dst->
getType();
1332 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1333 unsigned DstBits = DstTy->getScalarSizeInBits();
1340 if (SrcSigned == DstSigned && SrcBits == DstBits)
1344 if (!SrcSigned && !DstSigned)
1349 if ((DstBits > SrcBits) && DstSigned)
1351 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1352 (SrcBits > DstBits) && SrcSigned) {
1361 if (!OBTrapInvolved) {
1364 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1368 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1373 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1374 SanitizerDebugLocation SanScope(
1376 {SanitizerKind::SO_ImplicitIntegerSignChange,
1377 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1378 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1381 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1382 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1386 ImplicitConversionCheckKind CheckKind;
1387 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1394 CheckKind = Check.first;
1395 Checks.emplace_back(Check.second);
1397 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1398 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1404 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1405 Checks.emplace_back(Check.second);
1409 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1410 if (OBTrapInvolved) {
1411 llvm::Value *Combined = Check.second.first;
1412 for (
const auto &
C : Checks)
1413 Combined = Builder.CreateAnd(Combined,
C.first);
1419 llvm::Constant *StaticArgs[] = {
1422 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1423 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1425 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1430static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1431 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1437 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1438 if (!SrcSigned && !DstSigned)
1439 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1441 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1443 llvm::Value *Check =
nullptr;
1445 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1447 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1450 return std::make_pair(
1452 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1457static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1458 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1462 llvm::Value *SrcIsNegative =
1465 llvm::Value *DstIsNegative =
1471 llvm::Value *Check =
nullptr;
1473 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1475 return std::make_pair(
1476 ScalarExprEmitter::ICCK_IntegerSignChange,
1477 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1485 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1503 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1504 unsigned DstBits = Info.
Size;
1509 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1511 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1513 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1514 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1518 bool EmitTruncation = DstBits < SrcBits;
1522 bool EmitTruncationFromUnsignedToSigned =
1523 EmitTruncation && DstSigned && !SrcSigned;
1525 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1526 bool BothUnsigned = !SrcSigned && !DstSigned;
1527 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1534 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1539 else if (EmitSignChange) {
1540 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1541 "either the widths should be different, or the signednesses.");
1547 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1548 if (EmitTruncationFromUnsignedToSigned)
1549 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1551 llvm::Constant *StaticArgs[] = {
1554 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1555 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1557 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1561 QualType DstType, llvm::Type *SrcTy,
1563 ScalarConversionOpts Opts) {
1565 llvm::Type *SrcElementTy;
1566 llvm::Type *DstElementTy;
1576 "cannot cast between matrix and non-matrix types");
1577 SrcElementTy = SrcTy;
1578 DstElementTy = DstTy;
1579 SrcElementType = SrcType;
1580 DstElementType = DstType;
1585 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1590 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1592 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1593 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1597 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1604 llvm::Intrinsic::ID IID =
1605 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1606 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1610 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1611 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1614 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1615 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1616 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1618 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1619 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1620 return Builder.CreateFPExt(Src, DstTy,
"conv");
1625Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1628 ScalarConversionOpts Opts) {
1643 return Builder.CreateIsNotNull(Src,
"tobool");
1646 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1649 "Unhandled scalar conversion from a fixed point type to another type.");
1653 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1656 "Unhandled scalar conversion to a fixed point type from another type.");
1659 QualType NoncanonicalSrcType = SrcType;
1660 QualType NoncanonicalDstType = DstType;
1664 if (SrcType == DstType)
return Src;
1668 llvm::Value *OrigSrc = Src;
1669 QualType OrigSrcType = SrcType;
1670 llvm::Type *SrcTy = Src->
getType();
1674 return EmitConversionToBool(Src, SrcType);
1676 llvm::Type *DstTy = ConvertType(DstType);
1685 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1686 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1687 bool OBTrapInvolved =
1688 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1689 bool OBWrapInvolved =
1690 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1695 if (DstTy->isFloatingPointTy()) {
1698 return Builder.CreateFPExt(BitCast, DstTy,
"conv");
1707 Src = Builder.CreateBitCast(Src, CGF.
CGM.
HalfTy);
1710 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1717 if (SrcTy == DstTy) {
1718 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1719 (OBTrapInvolved && !OBWrapInvolved))
1720 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1721 NoncanonicalDstType, Loc, OBTrapInvolved);
1729 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1734 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1739 llvm::Value* IntResult =
1740 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1742 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1748 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1755 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1757 "Splatted expr doesn't match with vector element type?");
1761 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1765 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1769 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1770 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1771 if (SrcSize == DstSize)
1772 return Builder.CreateBitCast(Src, DstTy,
"conv");
1785 assert(((SrcElementTy->isIntegerTy() &&
1786 DstElementTy->isIntegerTy()) ||
1787 (SrcElementTy->isFloatingPointTy() &&
1788 DstElementTy->isFloatingPointTy())) &&
1789 "unexpected conversion between a floating-point vector and an "
1793 if (SrcElementTy->isIntegerTy())
1794 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1797 if (SrcSize > DstSize)
1798 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1801 return Builder.CreateFPExt(Src, DstTy,
"conv");
1805 Value *Res =
nullptr;
1806 llvm::Type *ResTy = DstTy;
1813 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1815 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1821 if (SrcTy->isFloatingPointTy()) {
1830 assert(DstTy->isIntegerTy(16) &&
1832 "Only half FP requires extra conversion");
1833 return Builder.CreateBitCast(Res, DstTy);
1839 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1841 if (DstTy != ResTy) {
1842 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1845 assert(ResTy->isIntegerTy(16) &&
1847 "Only half FP requires extra conversion");
1848 Res = Builder.CreateBitCast(Res, ResTy);
1852 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1853 !OBWrapInvolved && !Opts.PatternExcluded)
1854 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1855 NoncanonicalDstType, Loc, OBTrapInvolved);
1857 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1858 (OBTrapInvolved && !OBWrapInvolved))
1859 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1860 NoncanonicalDstType, Loc, OBTrapInvolved);
1865Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1867 SourceLocation Loc) {
1868 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1871 Result = FPBuilder.CreateFloatingToFixed(Src,
1874 Result = FPBuilder.CreateFixedToFloating(Src,
1876 ConvertType(DstTy));
1882 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1883 DstFPSema.getWidth(),
1884 DstFPSema.isSigned());
1886 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1889 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1896Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1898 SourceLocation Loc) {
1900 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1905 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1906 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1907 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1914 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1917Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1925void ScalarExprEmitter::EmitBinOpCheck(
1926 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1927 const BinOpInfo &Info) {
1930 SmallVector<llvm::Constant *, 4> StaticData;
1931 SmallVector<llvm::Value *, 2> DynamicData;
1939 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1940 if (UO && UO->
getOpcode() == UO_Minus) {
1941 Check = SanitizerHandler::NegateOverflow;
1943 DynamicData.push_back(Info.RHS);
1947 Check = SanitizerHandler::ShiftOutOfBounds;
1949 StaticData.push_back(
1951 StaticData.push_back(
1953 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1955 Check = SanitizerHandler::DivremOverflow;
1959 int ArithOverflowKind = 0;
1962 Check = SanitizerHandler::AddOverflow;
1963 ArithOverflowKind = diag::UBSanArithKind::Add;
1967 Check = SanitizerHandler::SubOverflow;
1968 ArithOverflowKind = diag::UBSanArithKind::Sub;
1972 Check = SanitizerHandler::MulOverflow;
1973 ArithOverflowKind = diag::UBSanArithKind::Mul;
1977 llvm_unreachable(
"unexpected opcode for bin op check");
1981 SanitizerKind::UnsignedIntegerOverflow) ||
1983 SanitizerKind::SignedIntegerOverflow)) {
1987 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1991 DynamicData.push_back(Info.LHS);
1992 DynamicData.push_back(Info.RHS);
1995 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
2002Value *ScalarExprEmitter::VisitExpr(Expr *E) {
2010ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
2012 unsigned AddrSpace =
2014 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
2017 llvm::Type *ExprTy = ConvertType(E->
getType());
2018 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2022Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2024 auto It = E->
begin();
2025 return Builder.getInt((*It)->getValue());
2028Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2036 unsigned LHSElts = LTy->getNumElements();
2044 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2045 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2053 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2054 MTy->getNumElements());
2055 Value* NewV = llvm::PoisonValue::get(RTy);
2056 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2057 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2058 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2060 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2061 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2069 SmallVector<int, 32> Indices;
2073 if (Idx.isSigned() && Idx.isAllOnes())
2074 Indices.push_back(-1);
2076 Indices.push_back(Idx.getZExtValue());
2079 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2082Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2090 if (SrcType == DstType)
return Src;
2093 "ConvertVector source type must be a vector");
2095 "ConvertVector destination type must be a vector");
2097 llvm::Type *SrcTy = Src->
getType();
2098 llvm::Type *DstTy = ConvertType(DstType);
2104 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2105 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2107 assert(SrcTy->isVectorTy() &&
2108 "ConvertVector source IR type must be a vector");
2109 assert(DstTy->isVectorTy() &&
2110 "ConvertVector destination IR type must be a vector");
2115 if (DstEltType->isBooleanType()) {
2116 assert((SrcEltTy->isFloatingPointTy() ||
2119 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2120 if (SrcEltTy->isFloatingPointTy()) {
2121 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2122 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2124 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2129 Value *Res =
nullptr;
2134 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2136 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2138 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2140 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2143 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2144 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2145 if (DstEltType->isSignedIntegerOrEnumerationType())
2146 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2148 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2150 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2151 "Unknown real conversion");
2152 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2153 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2154 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2156 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2162Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2171 return Builder.getInt(
Value);
2175 llvm::Value *
Result = EmitLoadOfLValue(E);
2181 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2182 if (llvm::GetElementPtrInst *GEP =
2183 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2184 if (llvm::Instruction *
Pointer =
2185 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2197Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2198 TestAndClearIgnoreResultAssign();
2206 return EmitLoadOfLValue(E);
2214 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2217 Value *
Ret = Builder.CreateExtractElement(Base, Idx,
"vecext");
2221 Ret = Builder.CreateInsertElement(
2222 llvm::PoisonValue::get(llvm::FixedVectorType::get(CGF.
Int8Ty, 1)), Ret,
2228Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2229 MatrixSingleSubscriptExpr *E) {
2230 TestAndClearIgnoreResultAssign();
2233 unsigned NumRows = MatrixTy->getNumRows();
2234 unsigned NumColumns = MatrixTy->getNumColumns();
2238 llvm::MatrixBuilder MB(Builder);
2242 MB.CreateIndexAssumption(RowIdx, NumRows);
2246 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2247 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2249 bool IsMatrixRowMajor =
2252 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2253 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2254 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2255 IsMatrixRowMajor,
"matrix_row_idx");
2257 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2258 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2259 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2265Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2266 TestAndClearIgnoreResultAssign();
2274 llvm::MatrixBuilder MB(Builder);
2277 unsigned NumCols = MatrixTy->getNumColumns();
2278 unsigned NumRows = MatrixTy->getNumRows();
2279 bool IsMatrixRowMajor =
2281 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2284 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2289 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2294 int MV = SVI->getMaskValue(Idx);
2301 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2302 "Index operand too large for shufflevector mask!");
2303 return C->getZExtValue();
2306Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2307 bool Ignore = TestAndClearIgnoreResultAssign();
2310 assert((Ignore ==
false ||
2312 "init list ignored");
2329 llvm::VectorType *VType =
2330 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2333 if (NumInitElements == 0) {
2335 return EmitNullValue(E->
getType());
2342 if (NumInitElements == 0) {
2344 return EmitNullValue(E->
getType());
2347 if (NumInitElements == 1) {
2348 Expr *InitVector = E->
getInit(0);
2353 return Visit(InitVector);
2356 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2363 const ConstantMatrixType *ColMajorMT =
nullptr;
2364 if (
const auto *MT = E->
getType()->
getAs<ConstantMatrixType>();
2373 unsigned CurIdx = 0;
2374 bool VIsPoisonShuffle =
false;
2375 llvm::Value *
V = llvm::PoisonValue::get(VType);
2376 for (
unsigned i = 0; i != NumInitElements; ++i) {
2379 SmallVector<int, 16> Args;
2381 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2391 ->getNumElements() == ResElts) {
2393 Value *LHS =
nullptr, *RHS =
nullptr;
2398 Args.resize(ResElts, -1);
2400 LHS = EI->getVectorOperand();
2402 VIsPoisonShuffle =
true;
2403 }
else if (VIsPoisonShuffle) {
2406 for (
unsigned j = 0; j != CurIdx; ++j)
2408 Args.push_back(ResElts +
C->getZExtValue());
2409 Args.resize(ResElts, -1);
2412 RHS = EI->getVectorOperand();
2413 VIsPoisonShuffle =
false;
2415 if (!Args.empty()) {
2416 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2422 unsigned InsertIdx =
2426 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(InsertIdx),
2428 VIsPoisonShuffle =
false;
2438 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2441 Value *SVOp = SVI->getOperand(0);
2444 if (OpTy->getNumElements() == ResElts) {
2445 for (
unsigned j = 0; j != CurIdx; ++j) {
2448 if (VIsPoisonShuffle) {
2454 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2456 Args.resize(ResElts, -1);
2458 if (VIsPoisonShuffle)
2468 for (
unsigned j = 0; j != InitElts; ++j)
2470 Args.resize(ResElts, -1);
2471 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2474 for (
unsigned j = 0; j != CurIdx; ++j)
2476 for (
unsigned j = 0; j != InitElts; ++j)
2477 Args.push_back(j + Offset);
2478 Args.resize(ResElts, -1);
2485 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2492 llvm::Type *EltTy = VType->getElementType();
2495 for (; CurIdx < ResElts; ++CurIdx) {
2496 unsigned InsertIdx =
2499 Value *Idx = Builder.getInt32(InsertIdx);
2500 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2501 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2514 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2518 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2521 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2540 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2544 if (
const auto *CE = dyn_cast<CastExpr>(E))
2545 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2546 CE->getCastKind() == CK_ArrayToPointerDecay)
2557 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2567 if (ICE->isGLValue())
2582 assert(LoadList.size() >= VecTy->getNumElements() &&
2583 "Flattened type on RHS must have the same number or more elements "
2584 "than vector on LHS.");
2588 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2591 "All flattened source values should be scalars.");
2594 VecTy->getElementType(), Loc);
2595 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2600 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2601 "Flattened type on RHS must have the same number or more elements "
2602 "than vector on LHS.");
2609 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2610 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2613 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2616 "All flattened source values should be scalars.");
2619 MatTy->getElementType(), Loc);
2620 unsigned MatrixIdx = MatTy->getFlattenedIndex(Row, Col, IsRowMajor);
2621 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2628 "Destination type must be a vector, matrix, or builtin type.");
2630 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2639 llvm::scope_exit RestoreCurCast(
2640 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2644 QualType DestTy = CE->
getType();
2646 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2650 bool Ignored = TestAndClearIgnoreResultAssign();
2656 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2657 case CK_BuiltinFnToFnPtr:
2658 llvm_unreachable(
"builtin functions are handled elsewhere");
2660 case CK_LValueBitCast:
2661 case CK_ObjCObjectLValueCast: {
2665 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2668 case CK_LValueToRValueBitCast: {
2674 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2677 case CK_CPointerToObjCPointerCast:
2678 case CK_BlockPointerToObjCPointerCast:
2679 case CK_AnyPointerToBlockPointerCast:
2681 Value *Src = Visit(E);
2682 llvm::Type *SrcTy = Src->
getType();
2683 llvm::Type *DstTy = ConvertType(DestTy);
2694 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2708 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2709 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2714 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2715 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2716 "Address-space cast must be used to convert address spaces");
2718 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2719 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2721 PT->getPointeeType(),
2732 const QualType SrcType = E->
getType();
2737 Src = Builder.CreateLaunderInvariantGroup(Src);
2745 Src = Builder.CreateStripInvariantGroup(Src);
2750 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2754 if (!PointeeType.
isNull())
2763 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2764 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2767 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2768 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2769 ScalableDstTy = llvm::ScalableVectorType::get(
2770 FixedSrcTy->getElementType(),
2772 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2774 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2775 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2776 llvm::Value *
Result = Builder.CreateInsertVector(
2777 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2779 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2780 if (
Result->getType() != ScalableDstTy)
2782 if (
Result->getType() != DstTy)
2792 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2793 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2796 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2797 FixedDstTy->getElementType()->isIntegerTy(8)) {
2798 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2799 ScalableSrcTy = llvm::ScalableVectorType::get(
2800 ScalableSrcTy->getElementType(),
2802 ScalableSrcTy->getElementCount().getKnownMinValue()));
2803 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2804 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2808 ScalableSrcTy = llvm::ScalableVectorType::get(
2809 FixedDstTy->getElementType(),
2810 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2811 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2813 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2814 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2835 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2838 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2841 case CK_AddressSpaceConversion: {
2844 Result.Val.isNullPointer()) {
2848 if (
Result.HasSideEffects)
2851 ConvertType(DestTy)), DestTy);
2857 case CK_AtomicToNonAtomic:
2858 case CK_NonAtomicToAtomic:
2859 case CK_UserDefinedConversion:
2866 case CK_BaseToDerived: {
2868 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2882 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2890 case CK_UncheckedDerivedToBase:
2891 case CK_DerivedToBase: {
2904 case CK_ArrayToPointerDecay:
2907 case CK_FunctionToPointerDecay:
2908 return EmitLValue(E).getPointer(CGF);
2910 case CK_NullToPointer:
2911 if (MustVisitNullValue(E))
2917 case CK_NullToMemberPointer: {
2918 if (MustVisitNullValue(E))
2921 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2925 case CK_ReinterpretMemberPointer:
2926 case CK_BaseToDerivedMemberPointer:
2927 case CK_DerivedToBaseMemberPointer: {
2928 Value *Src = Visit(E);
2939 case CK_ARCProduceObject:
2941 case CK_ARCConsumeObject:
2943 case CK_ARCReclaimReturnedObject:
2945 case CK_ARCExtendBlockObject:
2948 case CK_CopyAndAutoreleaseBlockObject:
2951 case CK_FloatingRealToComplex:
2952 case CK_FloatingComplexCast:
2953 case CK_IntegralRealToComplex:
2954 case CK_IntegralComplexCast:
2955 case CK_IntegralComplexToFloatingComplex:
2956 case CK_FloatingComplexToIntegralComplex:
2957 case CK_ConstructorConversion:
2959 case CK_HLSLArrayRValue:
2960 llvm_unreachable(
"scalar cast to non-scalar value");
2962 case CK_LValueToRValue:
2964 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2967 case CK_IntegralToPointer: {
2968 Value *Src = Visit(E);
2972 auto DestLLVMTy = ConvertType(DestTy);
2975 llvm::Value* IntResult =
2976 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2978 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2984 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2990 case CK_PointerToIntegral: {
2991 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2992 auto *PtrExpr = Visit(E);
2995 const QualType SrcType = E->
getType();
3000 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
3004 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
3010 case CK_MatrixCast: {
3011 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3018 case CK_HLSLAggregateSplatCast:
3019 case CK_VectorSplat: {
3020 llvm::Type *DstTy = ConvertType(DestTy);
3021 Value *Elt = Visit(E);
3023 llvm::ElementCount NumElements =
3025 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
3028 case CK_FixedPointCast:
3029 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3032 case CK_FixedPointToBoolean:
3034 "Expected src type to be fixed point type");
3035 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
3036 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3039 case CK_FixedPointToIntegral:
3041 "Expected src type to be fixed point type");
3042 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
3043 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3046 case CK_IntegralToFixedPoint:
3048 "Expected src type to be an integer");
3050 "Expected dest type to be fixed point type");
3051 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3054 case CK_IntegralCast: {
3056 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3057 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3061 ScalarConversionOpts Opts;
3062 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3063 if (!ICE->isPartOfExplicitCast())
3064 Opts = ScalarConversionOpts(CGF.
SanOpts);
3066 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3069 case CK_IntegralToFloating: {
3072 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3074 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3075 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3077 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3078 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3081 case CK_FloatingToIntegral: {
3084 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3086 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3087 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3089 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3090 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3093 case CK_FloatingCast: {
3096 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3097 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3098 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3099 SrcElTy->
castAs<BuiltinType>()->getKind())
3100 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3101 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3103 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3104 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3107 case CK_FixedPointToFloating:
3108 case CK_FloatingToFixedPoint: {
3109 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3110 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3113 case CK_BooleanToSignedIntegral: {
3114 ScalarConversionOpts Opts;
3115 Opts.TreatBooleanAsSigned =
true;
3116 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3119 case CK_IntegralToBoolean:
3120 return EmitIntToBoolConversion(Visit(E));
3121 case CK_PointerToBoolean:
3122 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3123 case CK_FloatingToBoolean: {
3124 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3125 return EmitFloatToBoolConversion(Visit(E));
3127 case CK_MemberPointerToBoolean: {
3128 llvm::Value *MemPtr = Visit(E);
3129 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3133 case CK_FloatingComplexToReal:
3134 case CK_IntegralComplexToReal:
3137 case CK_FloatingComplexToBoolean:
3138 case CK_IntegralComplexToBoolean: {
3142 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3146 case CK_ZeroToOCLOpaqueType: {
3149 "CK_ZeroToOCLEvent cast on non-event type");
3150 return llvm::Constant::getNullValue(ConvertType(DestTy));
3153 case CK_IntToOCLSampler:
3156 case CK_HLSLVectorTruncation: {
3158 "Destination type must be a vector or builtin type.");
3159 Value *Vec = Visit(E);
3160 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3161 SmallVector<int> Mask;
3162 unsigned NumElts = VecTy->getNumElements();
3163 for (
unsigned I = 0; I != NumElts; ++I)
3166 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3168 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3169 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3171 case CK_HLSLMatrixTruncation: {
3173 "Destination type must be a matrix or builtin type.");
3174 Value *Mat = Visit(E);
3175 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3176 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3177 unsigned NumCols = MatTy->getNumColumns();
3178 unsigned NumRows = MatTy->getNumRows();
3179 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3180 assert(SrcMatTy &&
"Source type must be a matrix type.");
3181 assert(NumRows <= SrcMatTy->getNumRows());
3182 assert(NumCols <= SrcMatTy->getNumColumns());
3189 for (
unsigned R = 0;
R < NumRows;
R++)
3190 for (
unsigned C = 0;
C < NumCols;
C++)
3191 Mask[MatTy->getFlattenedIndex(R,
C, IsDstRowMajor)] =
3192 SrcMatTy->getFlattenedIndex(R,
C, IsSrcRowMajor);
3194 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3196 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3197 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3199 case CK_HLSLElementwiseCast: {
3219 llvm_unreachable(
"unknown scalar cast");
3222Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3223 CodeGenFunction::StmtExprEvaluation eval(CGF);
3232Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3233 CodeGenFunction::RunCleanupsScope Scope(CGF);
3237 Scope.ForceCleanup({&
V});
3246 llvm::Value *InVal,
bool IsInc,
3250 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3252 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3253 BinOp.FPFeatures = FPFeatures;
3258llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3259 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3262 llvm::Value *Amount =
3263 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3264 StringRef Name = IsInc ?
"inc" :
"dec";
3268 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3269 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3271 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3272 case LangOptions::OB_Wrap:
3273 return Builder.CreateAdd(InVal, Amount, Name);
3274 case LangOptions::OB_SignedAndDefined:
3276 return Builder.CreateAdd(InVal, Amount, Name);
3278 case LangOptions::OB_Unset:
3280 return Builder.CreateAdd(InVal, Amount, Name);
3282 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3283 : Builder.CreateAdd(InVal, Amount, Name);
3285 case LangOptions::OB_Trap:
3287 return Builder.CreateAdd(InVal, Amount, Name);
3290 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3291 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3292 : Builder.CreateAdd(InVal, Amount, Name);
3293 return EmitOverflowCheckedBinOp(Info);
3295 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3300class OMPLastprivateConditionalUpdateRAII {
3302 CodeGenFunction &CGF;
3303 const UnaryOperator *E;
3306 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3307 const UnaryOperator *E)
3309 ~OMPLastprivateConditionalUpdateRAII() {
3318ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3319 bool isInc,
bool isPre) {
3321 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3323 llvm::PHINode *atomicPHI =
nullptr;
3327 QualType SrcType = E->
getType();
3329 int amount = (isInc ? 1 : -1);
3330 bool isSubtraction = !isInc;
3332 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3333 type = atomicTy->getValueType();
3334 if (isInc &&
type->isBooleanType()) {
3337 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3338 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3339 return Builder.getTrue();
3343 return Builder.CreateAtomicRMW(
3344 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3345 llvm::AtomicOrdering::SequentiallyConsistent);
3350 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3351 !(
type->isUnsignedIntegerType() &&
3352 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3354 LangOptions::SOB_Trapping) {
3355 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3356 llvm::AtomicRMWInst::Sub;
3357 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3358 llvm::Instruction::Sub;
3360 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3362 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3363 llvm::AtomicOrdering::SequentiallyConsistent);
3364 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3368 if (
type->isFloatingType()) {
3369 llvm::Type *Ty = ConvertType(
type);
3370 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3371 llvm::AtomicRMWInst::BinOp aop =
3372 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3373 llvm::Instruction::BinaryOps op =
3374 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3375 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3376 llvm::AtomicRMWInst *old =
3378 llvm::AtomicOrdering::SequentiallyConsistent);
3380 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3383 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3386 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3389 Builder.CreateBr(opBB);
3390 Builder.SetInsertPoint(opBB);
3391 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3392 atomicPHI->addIncoming(value, startBB);
3395 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3406 if (isInc &&
type->isBooleanType()) {
3407 value = Builder.getTrue();
3410 }
else if (
type->isIntegerType()) {
3411 QualType promotedType;
3412 bool canPerformLossyDemotionCheck =
false;
3416 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3417 canPerformLossyDemotionCheck =
true;
3418 canPerformLossyDemotionCheck &=
3421 canPerformLossyDemotionCheck &=
3423 type, promotedType);
3424 assert((!canPerformLossyDemotionCheck ||
3425 type->isSignedIntegerOrEnumerationType() ||
3427 ConvertType(
type)->getScalarSizeInBits() ==
3428 ConvertType(promotedType)->getScalarSizeInBits()) &&
3429 "The following check expects that if we do promotion to different "
3430 "underlying canonical type, at least one of the types (either "
3431 "base or promoted) will be signed, or the bitwidths will match.");
3434 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3435 SanitizerKind::ImplicitBitfieldConversion) &&
3436 canPerformLossyDemotionCheck) {
3450 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3451 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3452 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3456 ScalarConversionOpts Opts;
3457 if (!LV.isBitField())
3458 Opts = ScalarConversionOpts(CGF.
SanOpts);
3459 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3461 SrcType = promotedType;
3465 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3471 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3472 type->isUnsignedIntegerType()) {
3473 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3478 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3479 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3483 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3484 QualType
type = ptr->getPointeeType();
3487 if (
const VariableArrayType *vla
3490 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3493 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3496 elemTy, value, numElts,
false, isSubtraction,
3500 }
else if (
type->isFunctionType()) {
3501 llvm::Value *amt = Builder.getInt32(amount);
3504 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3508 false, isSubtraction,
3513 llvm::Value *amt = Builder.getInt32(amount);
3516 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3519 elemTy, value, amt,
false, isSubtraction,
3524 }
else if (
type->isVectorType()) {
3525 if (
type->hasIntegerRepresentation()) {
3526 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3528 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3530 value = Builder.CreateFAdd(
3532 llvm::ConstantFP::get(value->getType(), amount),
3533 isInc ?
"inc" :
"dec");
3537 }
else if (
type->isRealFloatingType()) {
3540 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3546 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3549 if (value->getType()->isFloatTy())
3550 amt = llvm::ConstantFP::get(VMContext,
3551 llvm::APFloat(
static_cast<float>(amount)));
3552 else if (value->getType()->isDoubleTy())
3553 amt = llvm::ConstantFP::get(VMContext,
3554 llvm::APFloat(
static_cast<double>(amount)));
3558 llvm::APFloat F(
static_cast<float>(amount));
3560 const llvm::fltSemantics *FS;
3563 if (value->getType()->isFP128Ty())
3565 else if (value->getType()->isHalfTy())
3567 else if (value->getType()->isBFloatTy())
3569 else if (value->getType()->isPPC_FP128Ty())
3573 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3574 amt = llvm::ConstantFP::get(VMContext, F);
3576 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3579 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3580 value = Builder.CreateBitCast(value, input->getType());
3584 }
else if (
type->isFixedPointType()) {
3591 Info.Opcode = isInc ? BO_Add : BO_Sub;
3593 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3596 if (
type->isSignedFixedPointType()) {
3597 Info.Opcode = isInc ? BO_Sub : BO_Add;
3598 Info.RHS = Builder.CreateNeg(Info.RHS);
3603 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3605 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3606 value = EmitFixedPointBinOp(Info);
3610 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3613 if (!isInc) size = -size;
3614 llvm::Value *sizeValue =
3615 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3618 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3621 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3623 value = Builder.CreateBitCast(value, input->getType());
3627 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3632 llvm::Value *
success = Pair.second;
3633 atomicPHI->addIncoming(old, curBlock);
3634 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3635 Builder.SetInsertPoint(contBB);
3636 return isPre ? value : input;
3640 if (LV.isBitField()) {
3650 return isPre ? value : input;
3654Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3655 QualType PromotionType) {
3656 QualType promotionTy = PromotionType.
isNull()
3659 Value *result = VisitPlus(E, promotionTy);
3660 if (result && !promotionTy.
isNull())
3661 result = EmitUnPromotedValue(result, E->
getType());
3665Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3666 QualType PromotionType) {
3668 TestAndClearIgnoreResultAssign();
3669 if (!PromotionType.
isNull())
3674Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3675 QualType PromotionType) {
3676 QualType promotionTy = PromotionType.
isNull()
3679 Value *result = VisitMinus(E, promotionTy);
3680 if (result && !promotionTy.
isNull())
3681 result = EmitUnPromotedValue(result, E->
getType());
3685Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3686 QualType PromotionType) {
3687 TestAndClearIgnoreResultAssign();
3689 if (!PromotionType.
isNull())
3695 if (Op->
getType()->isFPOrFPVectorTy())
3696 return Builder.CreateFNeg(Op,
"fneg");
3701 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3703 BinOp.Opcode = BO_Sub;
3706 return EmitSub(BinOp);
3709Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3710 TestAndClearIgnoreResultAssign();
3712 return Builder.CreateNot(Op,
"not");
3715Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3719 VectorKind::Generic) {
3723 if (Oper->
getType()->isFPOrFPVectorTy()) {
3724 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3726 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3728 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3729 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3738 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3741 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3744Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3746 Expr::EvalResult EVResult;
3749 return Builder.getInt(
Value);
3754 llvm::Type* ResultType = ConvertType(E->
getType());
3755 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3757 for (
unsigned i = 0; i != n; ++i) {
3759 llvm::Value *Offset =
nullptr;
3766 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3773 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3777 Offset = Builder.CreateMul(Idx, ElemSize);
3782 FieldDecl *MemberDecl = ON.
getField();
3792 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3795 CurrentType = MemberDecl->
getType();
3800 llvm_unreachable(
"dependent __builtin_offsetof");
3817 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3829ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3830 const UnaryExprOrTypeTraitExpr *E) {
3833 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3834 if (
const VariableArrayType *VAT =
3839 bool EvaluateExtent =
true;
3840 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3842 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3844 if (EvaluateExtent) {
3855 if (Kind == UETT_CountOf)
3864 if (!eltSize.
isOne())
3867 return VlaSize.NumElts;
3870 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3876 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3877 }
else if (E->
getKind() == UETT_VectorElements) {
3879 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3887Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3888 QualType PromotionType) {
3889 QualType promotionTy = PromotionType.
isNull()
3892 Value *result = VisitReal(E, promotionTy);
3893 if (result && !promotionTy.
isNull())
3894 result = EmitUnPromotedValue(result, E->
getType());
3898Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3899 QualType PromotionType) {
3906 if (!PromotionType.
isNull()) {
3908 Op, IgnoreResultAssign,
true);
3923 if (!PromotionType.
isNull())
3928Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3929 QualType PromotionType) {
3930 QualType promotionTy = PromotionType.
isNull()
3933 Value *result = VisitImag(E, promotionTy);
3934 if (result && !promotionTy.
isNull())
3935 result = EmitUnPromotedValue(result, E->
getType());
3939Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3940 QualType PromotionType) {
3947 if (!PromotionType.
isNull()) {
3949 Op,
true, IgnoreResultAssign);
3953 return result.second
3969 else if (!PromotionType.
isNull())
3973 if (!PromotionType.
isNull())
3974 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3975 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3982Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3983 QualType PromotionType) {
3984 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3987Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3988 QualType ExprType) {
3989 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3992Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3994 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3996#define HANDLE_BINOP(OP) \
3998 return Emit##OP(EmitBinOps(BO, PromotionType));
4007 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
4010 return VisitImag(UO, PromotionType);
4012 return VisitReal(UO, PromotionType);
4014 return VisitMinus(UO, PromotionType);
4016 return VisitPlus(UO, PromotionType);
4021 auto result = Visit(
const_cast<Expr *
>(E));
4023 if (!PromotionType.
isNull())
4024 return EmitPromotedValue(result, PromotionType);
4026 return EmitUnPromotedValue(result, E->
getType());
4031BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4032 QualType PromotionType) {
4033 TestAndClearIgnoreResultAssign();
4037 if (!PromotionType.
isNull())
4038 Result.Ty = PromotionType;
4047LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4048 const CompoundAssignOperator *E,
4049 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4060 QualType PromotionTypeCR;
4062 if (PromotionTypeCR.
isNull())
4065 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4066 if (!PromotionTypeRHS.
isNull())
4069 OpInfo.RHS = Visit(E->
getRHS());
4070 OpInfo.Ty = PromotionTypeCR;
4077 llvm::PHINode *atomicPHI =
nullptr;
4078 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4079 QualType
type = atomicTy->getValueType();
4080 if (!
type->isBooleanType() &&
type->isIntegerType() &&
4081 !(
type->isUnsignedIntegerType() &&
4082 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4084 LangOptions::SOB_Trapping) {
4085 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4086 llvm::Instruction::BinaryOps Op;
4087 switch (OpInfo.Opcode) {
4089 case BO_MulAssign:
case BO_DivAssign:
4095 AtomicOp = llvm::AtomicRMWInst::Add;
4096 Op = llvm::Instruction::Add;
4099 AtomicOp = llvm::AtomicRMWInst::Sub;
4100 Op = llvm::Instruction::Sub;
4103 AtomicOp = llvm::AtomicRMWInst::And;
4104 Op = llvm::Instruction::And;
4107 AtomicOp = llvm::AtomicRMWInst::Xor;
4108 Op = llvm::Instruction::Xor;
4111 AtomicOp = llvm::AtomicRMWInst::Or;
4112 Op = llvm::Instruction::Or;
4115 llvm_unreachable(
"Invalid compound assignment type");
4117 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4119 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4123 llvm::AtomicRMWInst *OldVal =
4128 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4134 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4136 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4138 Builder.CreateBr(opBB);
4139 Builder.SetInsertPoint(opBB);
4140 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4141 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4142 OpInfo.LHS = atomicPHI;
4145 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4147 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4149 if (!PromotionTypeLHS.
isNull())
4150 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4153 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4164 if (LHSLV.isBitField()) {
4166 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4167 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4169 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4170 Loc, ScalarConversionOpts(CGF.
SanOpts));
4172 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4173 ScalarConversionOpts(CGF.
SanOpts));
4177 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4181 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4182 llvm::Value *
success = Pair.second;
4183 atomicPHI->addIncoming(old, curBlock);
4184 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4185 Builder.SetInsertPoint(contBB);
4193 if (LHSLV.isBitField()) {
4209Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4210 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4211 bool Ignore = TestAndClearIgnoreResultAssign();
4212 Value *RHS =
nullptr;
4213 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4224 if (!LHS.isVolatileQualified())
4228 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4231void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4232 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4233 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4236 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4237 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4238 SanitizerKind::SO_IntegerDivideByZero));
4242 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4243 Ops.Ty->hasSignedIntegerRepresentation() &&
4245 Ops.mayHaveIntegerOverflow() &&
4247 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4250 llvm::Value *IntMin =
4251 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4252 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4254 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4255 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4256 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4258 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4261 if (Checks.size() > 0)
4262 EmitBinOpCheck(Checks, Ops);
4265Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4267 SanitizerDebugLocation SanScope(&CGF,
4268 {SanitizerKind::SO_IntegerDivideByZero,
4269 SanitizerKind::SO_SignedIntegerOverflow,
4270 SanitizerKind::SO_FloatDivideByZero},
4271 SanitizerHandler::DivremOverflow);
4272 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4273 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4274 Ops.Ty->isIntegerType() &&
4275 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4276 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4277 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4278 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4279 Ops.Ty->isRealFloatingType() &&
4280 Ops.mayHaveFloatDivisionByZero()) {
4281 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4282 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4284 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4288 if (Ops.Ty->isConstantMatrixType()) {
4289 llvm::MatrixBuilder MB(Builder);
4296 "first operand must be a matrix");
4298 "second operand must be an arithmetic type");
4299 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4300 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4301 Ops.Ty->hasUnsignedIntegerRepresentation());
4304 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4306 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4307 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4311 else if (Ops.isFixedPointOp())
4312 return EmitFixedPointBinOp(Ops);
4313 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4314 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4316 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4319Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4321 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4322 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4323 Ops.Ty->isIntegerType() &&
4324 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4325 SanitizerDebugLocation SanScope(&CGF,
4326 {SanitizerKind::SO_IntegerDivideByZero,
4327 SanitizerKind::SO_SignedIntegerOverflow},
4328 SanitizerHandler::DivremOverflow);
4329 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4330 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4333 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4334 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4336 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4337 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4339 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4342Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4347 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4348 switch (Ops.Opcode) {
4352 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4353 llvm::Intrinsic::uadd_with_overflow;
4354 OverflowKind = SanitizerHandler::AddOverflow;
4359 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4360 llvm::Intrinsic::usub_with_overflow;
4361 OverflowKind = SanitizerHandler::SubOverflow;
4366 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4367 llvm::Intrinsic::umul_with_overflow;
4368 OverflowKind = SanitizerHandler::MulOverflow;
4371 llvm_unreachable(
"Unsupported operation for overflow detection");
4377 SanitizerDebugLocation SanScope(&CGF,
4378 {SanitizerKind::SO_SignedIntegerOverflow,
4379 SanitizerKind::SO_UnsignedIntegerOverflow},
4385 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4386 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4387 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4390 const std::string *handlerName =
4392 if (handlerName->empty()) {
4398 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4399 llvm::Value *NotOf = Builder.CreateNot(overflow);
4401 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4404 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4407 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4408 llvm::Value *NotOf = Builder.CreateNot(overflow);
4410 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4413 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4418 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4419 llvm::BasicBlock *continueBB =
4423 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4427 Builder.SetInsertPoint(overflowBB);
4430 llvm::Type *Int8Ty = CGF.
Int8Ty;
4431 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4432 llvm::FunctionType *handlerTy =
4433 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4434 llvm::FunctionCallee handler =
4439 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4440 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4444 llvm::Value *handlerArgs[] = {
4447 Builder.getInt8(OpID),
4450 llvm::Value *handlerResult =
4454 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4455 Builder.CreateBr(continueBB);
4457 Builder.SetInsertPoint(continueBB);
4458 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4459 phi->addIncoming(result, initialBB);
4460 phi->addIncoming(handlerResult, overflowBB);
4469 bool isSubtraction) {
4474 Value *pointer = op.LHS;
4475 Expr *pointerOperand =
expr->getLHS();
4477 Expr *indexOperand =
expr->getRHS();
4480 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4481 std::swap(pointer,
index);
4482 std::swap(pointerOperand, indexOperand);
4486 index, isSubtraction);
4492 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4496 auto &DL =
CGM.getDataLayout();
4519 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4521 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4522 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4523 PtrTy->getPointerAddressSpace()))
4526 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4527 auto CheckHandler = SanitizerHandler::PointerOverflow;
4529 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4531 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4532 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4534 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4535 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4540 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4551 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4561 llvm::Value *objectSize =
4567 return Builder.CreateBitCast(result, pointer->getType());
4572 getContext().getAsVariableArrayType(elementType)) {
4574 llvm::Value *numElements =
getVLASize(vla).NumElts;
4583 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4603 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4616 bool negMul,
bool negAdd) {
4617 Value *MulOp0 = MulOp->getOperand(0);
4618 Value *MulOp1 = MulOp->getOperand(1);
4620 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4622 Addend = Builder.CreateFNeg(Addend,
"neg");
4624 Value *FMulAdd =
nullptr;
4625 if (Builder.getIsFPConstrained()) {
4627 "Only constrained operation should be created when Builder is in FP "
4628 "constrained mode");
4629 FMulAdd = Builder.CreateConstrainedFPCall(
4630 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4632 {MulOp0, MulOp1, Addend});
4634 FMulAdd = Builder.CreateCall(
4636 {MulOp0, MulOp1, Addend});
4638 MulOp->eraseFromParent();
4653 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4654 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4655 "Only fadd/fsub can be the root of an fmuladd.");
4658 if (!op.FPFeatures.allowFPContractWithinStatement())
4661 Value *LHS = op.LHS;
4662 Value *RHS = op.RHS;
4666 bool NegLHS =
false;
4667 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4668 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4669 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4670 LHS = LHSUnOp->getOperand(0);
4675 bool NegRHS =
false;
4676 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4677 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4678 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4679 RHS = RHSUnOp->getOperand(0);
4687 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4688 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4689 (LHSBinOp->use_empty() || NegLHS)) {
4693 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4696 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4697 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4698 (RHSBinOp->use_empty() || NegRHS)) {
4702 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4706 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4707 if (LHSBinOp->getIntrinsicID() ==
4708 llvm::Intrinsic::experimental_constrained_fmul &&
4709 (LHSBinOp->use_empty() || NegLHS)) {
4713 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4716 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4717 if (RHSBinOp->getIntrinsicID() ==
4718 llvm::Intrinsic::experimental_constrained_fmul &&
4719 (RHSBinOp->use_empty() || NegRHS)) {
4723 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4730Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4731 if (op.LHS->getType()->isPointerTy() ||
4732 op.RHS->getType()->isPointerTy())
4735 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4736 op.Ty->isUnsignedIntegerType()) {
4737 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4739 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4740 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4741 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4742 case LangOptions::OB_Wrap:
4743 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4744 case LangOptions::OB_SignedAndDefined:
4746 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4748 case LangOptions::OB_Unset:
4750 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4751 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4753 case LangOptions::OB_Trap:
4754 if (CanElideOverflowCheck(CGF.
getContext(), op))
4755 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4756 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4757 return EmitOverflowCheckedBinOp(op);
4762 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4763 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4769 if (op.Ty->isConstantMatrixType()) {
4770 llvm::MatrixBuilder MB(Builder);
4771 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4772 return MB.CreateAdd(op.LHS, op.RHS);
4775 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4776 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4777 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4780 if (op.isFixedPointOp())
4781 return EmitFixedPointBinOp(op);
4783 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4788Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4790 using llvm::ConstantInt;
4796 QualType ResultTy = op.Ty;
4797 QualType LHSTy, RHSTy;
4798 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4799 RHSTy = BinOp->getRHS()->getType();
4800 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4805 LHSTy = CAO->getComputationLHSType();
4806 ResultTy = CAO->getComputationResultType();
4808 LHSTy = BinOp->getLHS()->getType();
4809 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4810 LHSTy = UnOp->getSubExpr()->getType();
4811 RHSTy = UnOp->getSubExpr()->getType();
4814 Value *LHS = op.LHS;
4815 Value *RHS = op.RHS;
4820 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4824 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4825 switch (op.Opcode) {
4828 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4832 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4836 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4840 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4844 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4848 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4851 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4853 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4855 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4857 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4862 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4864 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4868 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4881 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4887 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4892Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4894 if (!op.LHS->getType()->isPointerTy()) {
4895 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4896 op.Ty->isUnsignedIntegerType()) {
4897 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4899 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4900 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4901 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4902 case LangOptions::OB_Wrap:
4903 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4904 case LangOptions::OB_SignedAndDefined:
4906 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4908 case LangOptions::OB_Unset:
4910 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4911 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4913 case LangOptions::OB_Trap:
4914 if (CanElideOverflowCheck(CGF.
getContext(), op))
4915 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4916 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4917 return EmitOverflowCheckedBinOp(op);
4922 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4923 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4929 if (op.Ty->isConstantMatrixType()) {
4930 llvm::MatrixBuilder MB(Builder);
4931 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4932 return MB.CreateSub(op.LHS, op.RHS);
4935 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4936 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4937 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4940 if (op.isFixedPointOp())
4941 return EmitFixedPointBinOp(op);
4943 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4948 if (!op.RHS->getType()->isPointerTy())
4955 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4957 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4958 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4962 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4964 llvm::Value *divisor =
nullptr;
4967 if (
const VariableArrayType *vla
4970 elementType = VlaSize.Type;
4971 divisor = VlaSize.NumElts;
4975 if (!eltSize.
isOne())
4982 CharUnits elementSize;
4991 if (elementSize.
isOne())
5000 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
5003Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
5005 llvm::IntegerType *Ty;
5006 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5014 llvm::Type *RHSTy = RHS->
getType();
5015 llvm::APInt RHSMax =
5016 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5017 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5018 if (RHSMax.ult(Ty->getBitWidth()))
5019 return llvm::ConstantInt::get(RHSTy, RHSMax);
5020 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5024 const Twine &Name) {
5025 llvm::IntegerType *Ty;
5026 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5031 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5032 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5034 return Builder.CreateURem(
5035 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5038Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5040 if (Ops.isFixedPointOp())
5041 return EmitFixedPointBinOp(Ops);
5045 Value *RHS = Ops.RHS;
5046 if (Ops.LHS->getType() != RHS->
getType())
5047 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5049 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5050 Ops.Ty->hasSignedIntegerRepresentation() &&
5053 bool SanitizeUnsignedBase =
5054 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5055 Ops.Ty->hasUnsignedIntegerRepresentation();
5056 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5057 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5060 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5061 else if ((SanitizeBase || SanitizeExponent) &&
5063 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5064 if (SanitizeSignedBase)
5065 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5066 if (SanitizeUnsignedBase)
5067 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5068 if (SanitizeExponent)
5069 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5071 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5072 SanitizerHandler::ShiftOutOfBounds);
5073 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5074 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5075 llvm::Value *WidthMinusOne =
5076 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5077 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5079 if (SanitizeExponent) {
5081 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5088 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5091 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5092 llvm::Value *PromotedWidthMinusOne =
5093 (RHS == Ops.RHS) ? WidthMinusOne
5094 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5096 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5097 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5106 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5107 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5109 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5110 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5112 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5113 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5114 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5115 Checks.push_back(std::make_pair(
5116 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5117 : SanitizerKind::SO_UnsignedShiftBase));
5120 assert(!Checks.empty());
5121 EmitBinOpCheck(Checks, Ops);
5124 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5127Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5129 if (Ops.isFixedPointOp())
5130 return EmitFixedPointBinOp(Ops);
5134 Value *RHS = Ops.RHS;
5135 if (Ops.LHS->getType() != RHS->
getType())
5136 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5140 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5141 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5143 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5144 SanitizerHandler::ShiftOutOfBounds);
5145 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5146 llvm::Value *
Valid = Builder.CreateICmpULE(
5147 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5148 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5151 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5152 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5153 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5161 default: llvm_unreachable(
"unexpected element type");
5162 case BuiltinType::Char_U:
5163 case BuiltinType::UChar:
5164 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5165 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5166 case BuiltinType::Char_S:
5167 case BuiltinType::SChar:
5168 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5169 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5170 case BuiltinType::UShort:
5171 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5172 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5173 case BuiltinType::Short:
5174 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5175 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5176 case BuiltinType::UInt:
5177 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5178 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5179 case BuiltinType::Int:
5180 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5181 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5182 case BuiltinType::ULong:
5183 case BuiltinType::ULongLong:
5184 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5185 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5186 case BuiltinType::Long:
5187 case BuiltinType::LongLong:
5188 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5189 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5190 case BuiltinType::Float:
5191 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5192 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5193 case BuiltinType::Double:
5194 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5195 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5196 case BuiltinType::UInt128:
5197 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5198 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5199 case BuiltinType::Int128:
5200 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5201 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5205Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5206 llvm::CmpInst::Predicate UICmpOpc,
5207 llvm::CmpInst::Predicate SICmpOpc,
5208 llvm::CmpInst::Predicate FCmpOpc,
5210 TestAndClearIgnoreResultAssign();
5214 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5220 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5222 BinOpInfo BOInfo = EmitBinOps(E);
5223 Value *LHS = BOInfo.LHS;
5224 Value *RHS = BOInfo.RHS;
5230 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5232 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5235 Value *FirstVecArg = LHS,
5236 *SecondVecArg = RHS;
5238 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5242 default: llvm_unreachable(
"is not a comparison operation");
5254 std::swap(FirstVecArg, SecondVecArg);
5261 if (ElementKind == BuiltinType::Float) {
5263 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5264 std::swap(FirstVecArg, SecondVecArg);
5272 if (ElementKind == BuiltinType::Float) {
5274 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5279 std::swap(FirstVecArg, SecondVecArg);
5284 Value *CR6Param = Builder.getInt32(CR6);
5286 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5294 if (ResultTy->getBitWidth() > 1 &&
5296 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5301 if (BOInfo.isFixedPointOp()) {
5302 Result = EmitFixedPointBinOp(BOInfo);
5303 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5304 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5306 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5308 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5310 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5325 LHS = Builder.CreateStripInvariantGroup(LHS);
5327 RHS = Builder.CreateStripInvariantGroup(RHS);
5330 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5336 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5342 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5344 CETy = CTy->getElementType();
5346 LHS.first = Visit(E->
getLHS());
5347 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5350 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5353 CTy->getElementType()) &&
5354 "The element types must always match.");
5357 RHS.first = Visit(E->
getRHS());
5358 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5360 "The element types must always match.");
5363 Value *ResultR, *ResultI;
5367 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5368 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5372 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5373 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5377 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5380 "Complex comparison other than == or != ?");
5381 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5393 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5394 CastKind Kind = ICE->getCastKind();
5395 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5396 *SrcType = ICE->getSubExpr()->getType();
5409 bool Ignore = TestAndClearIgnoreResultAssign();
5443 RHS = Visit(E->
getRHS());
5459 RHS = Visit(E->
getRHS());
5499 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5502Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5513 if (LHS->
getType()->isFPOrFPVectorTy()) {
5514 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5516 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5517 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5519 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5520 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5522 Value *
And = Builder.CreateAnd(LHS, RHS);
5523 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5527 llvm::Type *ResTy = ConvertType(E->
getType());
5546 if (InstrumentRegions &&
5550 llvm::BasicBlock *RHSSkip =
5553 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5570 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5581 return llvm::Constant::getNullValue(ResTy);
5592 llvm::BasicBlock *LHSFalseBlock =
5595 CodeGenFunction::ConditionalEvaluation eval(CGF);
5610 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5612 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5614 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5623 RHSBlock = Builder.GetInsertBlock();
5628 llvm::BasicBlock *ContIncoming = RHSBlock;
5629 if (InstrumentRegions &&
5633 llvm::BasicBlock *RHSBlockSkip =
5635 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5639 PN->addIncoming(RHSCond, RHSBlockCnt);
5644 ContIncoming = RHSBlockSkip;
5655 PN->addIncoming(RHSCond, ContIncoming);
5664 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5668 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5671Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5682 if (LHS->
getType()->isFPOrFPVectorTy()) {
5683 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5685 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5686 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5688 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5689 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5691 Value *
Or = Builder.CreateOr(LHS, RHS);
5692 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5696 llvm::Type *ResTy = ConvertType(E->
getType());
5715 if (InstrumentRegions &&
5719 llvm::BasicBlock *RHSSkip =
5722 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5739 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5750 return llvm::ConstantInt::get(ResTy, 1);
5760 llvm::BasicBlock *LHSTrueBlock =
5763 CodeGenFunction::ConditionalEvaluation eval(CGF);
5779 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5781 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5783 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5795 RHSBlock = Builder.GetInsertBlock();
5800 llvm::BasicBlock *ContIncoming = RHSBlock;
5801 if (InstrumentRegions &&
5805 llvm::BasicBlock *RHSTrueBlock =
5807 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5811 PN->addIncoming(RHSCond, RHSBlockCnt);
5816 ContIncoming = RHSTrueBlock;
5823 PN->addIncoming(RHSCond, ContIncoming);
5830 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5833Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5836 return Visit(E->
getRHS());
5861Value *ScalarExprEmitter::
5862VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5863 TestAndClearIgnoreResultAssign();
5866 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5868 Expr *condExpr = E->
getCond();
5876 Expr *live = lhsExpr, *dead = rhsExpr;
5877 if (!CondExprBool) std::swap(live, dead);
5904 llvm::Value *LHS = Visit(lhsExpr);
5905 llvm::Value *RHS = Visit(rhsExpr);
5907 llvm::Type *condType = ConvertType(condExpr->
getType());
5910 unsigned numElem = vecTy->getNumElements();
5911 llvm::Type *elemType = vecTy->getElementType();
5913 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5914 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5915 llvm::Value *tmp = Builder.CreateSExt(
5916 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5917 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5920 llvm::Value *RHSTmp = RHS;
5921 llvm::Value *LHSTmp = LHS;
5922 bool wasCast =
false;
5924 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5925 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5926 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5930 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5931 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5932 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5934 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5944 llvm::Value *LHS = Visit(lhsExpr);
5945 llvm::Value *RHS = Visit(rhsExpr);
5947 llvm::Type *CondType = ConvertType(condExpr->
getType());
5950 if (VecTy->getElementType()->isIntegerTy(1))
5951 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5954 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5956 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5958 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5959 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5969 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5973 llvm::Value *LHS = Visit(lhsExpr);
5974 llvm::Value *RHS = Visit(rhsExpr);
5977 assert(!RHS &&
"LHS and RHS types must match");
5980 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5991 CodeGenFunction::ConditionalEvaluation eval(CGF);
6005 Value *LHS = Visit(lhsExpr);
6008 LHSBlock = Builder.GetInsertBlock();
6009 Builder.CreateBr(ContBlock);
6021 Value *RHS = Visit(rhsExpr);
6024 RHSBlock = Builder.GetInsertBlock();
6034 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6035 PN->addIncoming(LHS, LHSBlock);
6036 PN->addIncoming(RHS, RHSBlock);
6041Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6045Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6047 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6052Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6058 Value *Src,
unsigned NumElementsDst) {
6059 static constexpr int Mask[] = {0, 1, 2, -1};
6060 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6080 const llvm::DataLayout &DL,
6081 Value *Src, llvm::Type *DstTy,
6082 StringRef Name =
"") {
6086 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6087 return Builder.CreateBitCast(Src, DstTy, Name);
6090 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6091 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6094 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6096 if (!DstTy->isIntegerTy())
6097 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6099 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6103 if (!SrcTy->isIntegerTy())
6104 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6106 return Builder.CreateIntToPtr(Src, DstTy, Name);
6109Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6111 llvm::Type *DstTy = ConvertType(E->
getType());
6113 llvm::Type *SrcTy = Src->
getType();
6114 unsigned NumElementsSrc =
6118 unsigned NumElementsDst =
6129 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6134 Src->setName(
"astype");
6141 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6142 auto *Vec4Ty = llvm::FixedVectorType::get(
6148 Src->setName(
"astype");
6153 Src, DstTy,
"astype");
6156Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6168 "Invalid scalar expression to emit");
6170 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6171 .Visit(
const_cast<Expr *
>(E));
6180 "Invalid scalar expression to emit");
6181 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6191 "Invalid complex -> scalar conversion");
6192 return ScalarExprEmitter(*
this)
6193 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6200 if (!PromotionType.
isNull())
6201 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6203 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6209 bool isInc,
bool isPre) {
6210 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6220 llvm::Type *BaseTy =
6236 ScalarExprEmitter Scalar(*
this);
6239#define COMPOUND_OP(Op) \
6240 case BO_##Op##Assign: \
6241 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6278 llvm_unreachable(
"Not valid compound assignment operators");
6281 llvm_unreachable(
"Unhandled compound assignment operator");
6296 llvm::LLVMContext &VMContext,
6302 llvm::Value *TotalOffset =
nullptr;
6308 Value *BasePtr_int =
6309 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6311 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6312 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6313 return {TotalOffset, Builder.getFalse()};
6317 assert(GEP->getPointerOperand() == BasePtr &&
6318 "BasePtr must be the base of the GEP.");
6319 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6321 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6324 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6325 auto *SAddIntrinsic =
6326 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6327 auto *SMulIntrinsic =
6328 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6331 llvm::Value *OffsetOverflows = Builder.getFalse();
6335 llvm::Value *RHS) -> llvm::Value * {
6336 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6339 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6340 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6342 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6345 OffsetOverflows = Builder.getTrue();
6346 return llvm::ConstantInt::get(VMContext, N);
6351 auto *ResultAndOverflow = Builder.CreateCall(
6352 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6353 OffsetOverflows = Builder.CreateOr(
6354 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6355 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6359 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6360 GTI != GTE; ++GTI) {
6361 llvm::Value *LocalOffset;
6362 auto *Index = GTI.getOperand();
6364 if (
auto *STy = GTI.getStructTypeOrNull()) {
6368 LocalOffset = llvm::ConstantInt::get(
6369 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6374 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6375 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6376 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6381 if (!TotalOffset || TotalOffset ==
Zero)
6382 TotalOffset = LocalOffset;
6384 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6387 return {TotalOffset, OffsetOverflows};
6392 ArrayRef<Value *> IdxList,
6393 bool SignedIndices,
bool IsSubtraction,
6394 SourceLocation Loc,
const Twine &Name) {
6395 llvm::Type *PtrTy = Ptr->
getType();
6397 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6398 if (!SignedIndices && !IsSubtraction)
6399 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6401 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6404 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6408 bool PerformNullCheck = !NullPointerIsDefined(
6409 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6412 bool PerformOverflowCheck =
6415 if (!(PerformNullCheck || PerformOverflowCheck))
6418 const auto &DL = CGM.getDataLayout();
6420 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6421 auto CheckHandler = SanitizerHandler::PointerOverflow;
6422 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6423 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6425 GEPOffsetAndOverflow EvaluatedGEP =
6430 "If the offset got constant-folded, we don't expect that there was an "
6433 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6441 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6442 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6444 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6448 if (PerformNullCheck) {
6456 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6457 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6458 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6459 Checks.emplace_back(
Valid, CheckOrdinal);
6462 if (PerformOverflowCheck) {
6467 llvm::Value *ValidGEP;
6468 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6469 if (SignedIndices) {
6475 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6476 auto *PosOrZeroOffset =
6478 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6480 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6481 }
else if (!IsSubtraction) {
6486 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6492 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6494 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6495 Checks.emplace_back(ValidGEP, CheckOrdinal);
6498 assert(!Checks.empty() &&
"Should have produced some checks.");
6500 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6502 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6503 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6509 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6510 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6511 const Twine &Name) {
6512 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6513 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6514 if (!SignedIndices && !IsSubtraction)
6515 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6517 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6521 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6522 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6523 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 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)
Result
Implement __builtin_bit_cast and related operations.
Defines AST-level helper utilities for matrix types.
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.
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.
bool isUnaryOverflowPatternExcluded(const UnaryOperator *UO)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
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 * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
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.
@ UseSkipPath
Skip (false)
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)
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)
bool hasSkipCounter(const Stmt *S) const
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.
RawAddress CreateIRTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateIRTempWithoutCast - Create a temporary IR object of the given type, with appropriate alignment.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
void EmitBoundsCheck(const Expr *ArrayExpr, const Expr *ArrayExprBase, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
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...
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,...
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...
static const Expr * stripCond(const Expr *C)
Ignore parentheses and logical-NOT to track conditions consistently.
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)
void markStmtAsUsed(bool Skipped, const Stmt *S)
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 incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
bool isMCDCDecisionExpr(const Expr *E) const
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 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.
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.
unsigned mapRowMajorToColumnMajorFlattenedIndex(unsigned RowMajorIdx) const
Given a row-major flattened index RowMajorIdx, return the equivalent column-major flattened index.
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,...
@ 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.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
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
bool isSignedOverflowDefined() 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
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.
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.
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 conversions to and from __fp16 should go through an integer bitcast with i16.
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 isMFloat8Type() 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.
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 BitCast(InterpState &S, CodePtr OpPC)
@ Address
A pointer to a ValueDecl.
bool LE(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
PRESERVE_NONE bool Ret(InterpState &S, CodePtr &PC)
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())))
bool isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
@ Result
The result type of a method or function.
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::Type * HalfTy
half, bfloat, float, double
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.