35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/ADT/ScopeExit.h"
37#include "llvm/IR/Argument.h"
38#include "llvm/IR/CFG.h"
39#include "llvm/IR/Constants.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/DerivedTypes.h"
42#include "llvm/IR/FixedPointBuilder.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/GEPNoWrapFlags.h"
45#include "llvm/IR/GetElementPtrTypeIterator.h"
46#include "llvm/IR/GlobalVariable.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/IntrinsicsPowerPC.h"
49#include "llvm/IR/MatrixBuilder.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/TypeSize.h"
74bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
79 const auto &LHSAP = LHS->getValue();
80 const auto &RHSAP = RHS->getValue();
81 if (Opcode == BO_Add) {
83 : LHSAP.uadd_ov(RHSAP, Overflow);
84 }
else if (Opcode == BO_Sub) {
86 : LHSAP.usub_ov(RHSAP, Overflow);
87 }
else if (Opcode == BO_Mul) {
89 : LHSAP.umul_ov(RHSAP, Overflow);
90 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
91 if (
Signed && !RHS->isZero())
92 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
104 FPOptions FPFeatures;
108 bool mayHaveIntegerOverflow()
const {
110 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
111 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
112 if (!LHSCI || !RHSCI)
116 return ::mayHaveIntegerOverflow(
121 bool isDivremOp()
const {
127 bool mayHaveIntegerDivisionByZero()
const {
129 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
135 bool mayHaveFloatDivisionByZero()
const {
137 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
138 return CFP->isZero();
145 bool isFixedPointOp()
const {
148 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
149 QualType LHSType = BinOp->getLHS()->getType();
150 QualType RHSType = BinOp->getRHS()->getType();
153 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
154 return UnOp->getSubExpr()->getType()->isFixedPointType();
159 bool rhsHasSignedIntegerRepresentation()
const {
160 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
161 QualType RHSType = BinOp->getRHS()->getType();
168static bool MustVisitNullValue(
const Expr *E) {
191static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
201 const OverflowBehaviorType *OBT = Ty->
getAs<OverflowBehaviorType>();
206 switch (OBT->getBehaviorKind()) {
207 case OverflowBehaviorType::OverflowBehaviorKind::Wrap:
209 case OverflowBehaviorType::OverflowBehaviorKind::Trap:
212 llvm_unreachable(
"Unknown OverflowBehaviorKind");
219 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
227 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
231static bool CanElideOverflowCheck(
ASTContext &Ctx,
const BinOpInfo &Op) {
233 "Expected a unary or binary operator");
237 if (!Op.mayHaveIntegerOverflow())
244 const auto *BO = dyn_cast<BinaryOperator>(Op.E);
245 if (BO && BO->hasExcludedOverflowPattern())
248 if (Op.Ty.isWrapType())
250 if (Op.Ty.isTrapType())
253 if (Op.Ty->isSignedIntegerType() &&
259 if (Op.Ty->isUnsignedIntegerType() &&
284 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
290 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
291 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
295class ScalarExprEmitter
297 CodeGenFunction &CGF;
298 CGBuilderTy &Builder;
299 bool IgnoreResultAssign;
300 llvm::LLVMContext &VMContext;
303 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
304 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
305 VMContext(cgf.getLLVMContext()) {
312 bool TestAndClearIgnoreResultAssign() {
313 bool I = IgnoreResultAssign;
314 IgnoreResultAssign =
false;
318 llvm::Type *ConvertType(QualType T) {
return CGF.
ConvertType(T); }
319 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
325 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
326 const BinOpInfo &Info);
328 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
332 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
333 const AlignValueAttr *AVAttr =
nullptr;
334 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
335 const ValueDecl *VD = DRE->getDecl();
338 if (
const auto *TTy =
340 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
350 AVAttr = VD->
getAttr<AlignValueAttr>();
355 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
356 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
369 Value *EmitLoadOfLValue(
const Expr *E) {
373 EmitLValueAlignmentAssumption(E,
V);
379 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
383 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
384 Value *Src, QualType SrcType, QualType DstType,
385 llvm::Type *DstTy, SourceLocation Loc);
390 enum ImplicitConversionCheckKind :
unsigned char {
391 ICCK_IntegerTruncation = 0,
392 ICCK_UnsignedIntegerTruncation = 1,
393 ICCK_SignedIntegerTruncation = 2,
394 ICCK_IntegerSignChange = 3,
395 ICCK_SignedIntegerTruncationOrSignChange = 4,
400 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
401 QualType DstType, SourceLocation Loc,
402 bool OBTrapInvolved =
false);
407 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
408 QualType DstType, SourceLocation Loc,
409 bool OBTrapInvolved =
false);
413 struct ScalarConversionOpts {
414 bool TreatBooleanAsSigned;
415 bool EmitImplicitIntegerTruncationChecks;
416 bool EmitImplicitIntegerSignChangeChecks;
418 bool PatternExcluded;
420 ScalarConversionOpts()
421 : TreatBooleanAsSigned(
false),
422 EmitImplicitIntegerTruncationChecks(
false),
423 EmitImplicitIntegerSignChangeChecks(
false), PatternExcluded(
false) {}
425 ScalarConversionOpts(clang::SanitizerSet SanOpts)
426 : TreatBooleanAsSigned(
false),
427 EmitImplicitIntegerTruncationChecks(
428 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
429 EmitImplicitIntegerSignChangeChecks(
430 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)),
431 PatternExcluded(
false) {}
433 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
434 llvm::Type *SrcTy, llvm::Type *DstTy,
435 ScalarConversionOpts Opts);
437 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
439 ScalarConversionOpts Opts = ScalarConversionOpts());
443 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
449 QualType SrcTy, QualType DstTy,
453 Value *EmitNullValue(QualType Ty);
458 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
459 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
463 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
466 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
473 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
474 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
480 ZI->eraseFromParent();
485 return Builder.CreateIsNotNull(
V,
"tobool");
492 Value *Visit(Expr *E) {
493 ApplyDebugLocation DL(CGF, E);
494 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
497 Value *VisitStmt(Stmt *S) {
499 llvm_unreachable(
"Stmt can't have complex result type!");
501 Value *VisitExpr(Expr *S);
503 Value *VisitConstantExpr(ConstantExpr *E) {
509 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
524 Value *VisitParenExpr(ParenExpr *PE) {
527 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
530 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
531 return Visit(
GE->getResultExpr());
533 Value *VisitCoawaitExpr(CoawaitExpr *S) {
536 Value *VisitCoyieldExpr(CoyieldExpr *S) {
539 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
544 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
545 return Builder.getInt(E->
getValue());
547 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
548 return Builder.getInt(E->
getValue());
550 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
551 return llvm::ConstantFP::get(VMContext, E->
getValue());
553 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
556 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
559 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
560 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
562 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
563 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
565 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
569 return EmitNullValue(E->
getType());
571 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
572 return EmitNullValue(E->
getType());
574 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
575 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
576 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
578 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
581 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
585 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
589 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
590 Value *VisitEmbedExpr(EmbedExpr *E);
592 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
601 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
602 llvm_unreachable(
"Codegen for this isn't defined/implemented");
606 Value *VisitDeclRefExpr(DeclRefExpr *E) {
609 return EmitLoadOfLValue(E);
612 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
615 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
618 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
619 return EmitLoadOfLValue(E);
621 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
624 return EmitLoadOfLValue(E);
628 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
634 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
640 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
645 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
646 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
647 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
648 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
649 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
650 Value *VisitMemberExpr(MemberExpr *E);
651 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
652 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
653 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
659 return EmitLoadOfLValue(E);
662 Value *VisitInitListExpr(InitListExpr *E);
664 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
666 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
670 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
671 return EmitNullValue(E->
getType());
673 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
675 return VisitCastExpr(E);
679 Value *VisitCallExpr(
const CallExpr *E) {
681 return EmitLoadOfLValue(E);
685 EmitLValueAlignmentAssumption(E,
V);
689 Value *VisitStmtExpr(
const StmtExpr *E);
692 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
694 return EmitScalarPrePostIncDec(E, LV,
false,
false);
696 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
698 return EmitScalarPrePostIncDec(E, LV,
true,
false);
700 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
702 return EmitScalarPrePostIncDec(E, LV,
false,
true);
704 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
706 return EmitScalarPrePostIncDec(E, LV,
true,
true);
709 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
713 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
714 bool isInc,
bool isPre);
717 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
721 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
723 Value *VisitUnaryDeref(
const UnaryOperator *E) {
726 return EmitLoadOfLValue(E);
729 Value *VisitUnaryPlus(
const UnaryOperator *E,
730 QualType PromotionType = QualType());
731 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
732 Value *VisitUnaryMinus(
const UnaryOperator *E,
733 QualType PromotionType = QualType());
734 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
736 Value *VisitUnaryNot (
const UnaryOperator *E);
737 Value *VisitUnaryLNot (
const UnaryOperator *E);
738 Value *VisitUnaryReal(
const UnaryOperator *E,
739 QualType PromotionType = QualType());
740 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
741 Value *VisitUnaryImag(
const UnaryOperator *E,
742 QualType PromotionType = QualType());
743 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
744 Value *VisitUnaryExtension(
const UnaryOperator *E) {
749 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
750 return EmitLoadOfLValue(E);
752 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
760 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
761 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
764 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
765 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
768 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
772 Value *VisitExprWithCleanups(ExprWithCleanups *E);
773 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
776 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
781 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
783 return llvm::ConstantInt::get(ConvertType(E->
getType()),
786 return llvm::ConstantInt::get(ConvertType(E->
getType()),
790 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
798 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
799 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
802 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
803 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
806 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
816 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
817 return EmitNullValue(E->
getType());
820 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
825 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
826 return Builder.getInt1(E->
getValue());
830 Value *EmitMul(
const BinOpInfo &Ops) {
831 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
832 Ops.Ty->isUnsignedIntegerType()) {
833 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
835 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
836 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
837 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
838 case LangOptions::OB_Wrap:
839 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
840 case LangOptions::OB_SignedAndDefined:
842 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
844 case LangOptions::OB_Unset:
846 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
847 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
849 case LangOptions::OB_Trap:
850 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
851 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
852 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
853 return EmitOverflowCheckedBinOp(Ops);
857 if (Ops.Ty->isConstantMatrixType()) {
858 llvm::MatrixBuilder MB(Builder);
862 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
863 BO->getLHS()->getType().getCanonicalType());
864 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
865 BO->getRHS()->getType().getCanonicalType());
866 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
867 if (LHSMatTy && RHSMatTy)
868 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
869 LHSMatTy->getNumColumns(),
870 RHSMatTy->getNumColumns());
871 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
874 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
876 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
877 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
879 if (Ops.isFixedPointOp())
880 return EmitFixedPointBinOp(Ops);
881 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
885 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
888 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
889 llvm::Value *
Zero,
bool isDiv);
891 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
897 Value *EmitDiv(
const BinOpInfo &Ops);
898 Value *EmitRem(
const BinOpInfo &Ops);
899 Value *EmitAdd(
const BinOpInfo &Ops);
900 Value *EmitSub(
const BinOpInfo &Ops);
901 Value *EmitShl(
const BinOpInfo &Ops);
902 Value *EmitShr(
const BinOpInfo &Ops);
903 Value *EmitAnd(
const BinOpInfo &Ops) {
904 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
906 Value *EmitXor(
const BinOpInfo &Ops) {
907 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
909 Value *EmitOr (
const BinOpInfo &Ops) {
910 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
914 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
916 BinOpInfo EmitBinOps(
const BinaryOperator *E,
917 QualType PromotionTy = QualType());
919 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
920 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
921 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
923 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
924 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
927 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
928 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
930 QualType getPromotionType(QualType Ty) {
932 if (
auto *CT = Ty->
getAs<ComplexType>()) {
933 QualType ElementType = CT->getElementType();
939 if (
auto *VT = Ty->
getAs<VectorType>()) {
940 unsigned NumElements = VT->getNumElements();
950#define HANDLEBINOP(OP) \
951 Value *VisitBin##OP(const BinaryOperator *E) { \
952 QualType promotionTy = getPromotionType(E->getType()); \
953 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
954 if (result && !promotionTy.isNull()) \
955 result = EmitUnPromotedValue(result, E->getType()); \
958 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
959 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
960 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
976 llvm::CmpInst::Predicate SICmpOpc,
977 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
978#define VISITCOMP(CODE, UI, SI, FP, SIG) \
979 Value *VisitBin##CODE(const BinaryOperator *E) { \
980 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
981 llvm::FCmpInst::FP, SIG); }
982 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
996 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
997 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
999 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1004 Value *VisitBlockExpr(
const BlockExpr *BE);
1005 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1006 Value *VisitChooseExpr(ChooseExpr *CE);
1007 Value *VisitVAArgExpr(VAArgExpr *VE);
1008 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1011 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1014 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1017 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1020 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1021 Value *VisitAtomicExpr(AtomicExpr *AE);
1022 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1035 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1038 return EmitFloatToBoolConversion(Src);
1040 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1044 if (SrcType == CGF.
getContext().AMDGPUFeaturePredicateTy)
1048 "Unknown scalar type to convert");
1051 return EmitIntToBoolConversion(Src);
1054 return EmitPointerToBoolConversion(Src, SrcType);
1057void ScalarExprEmitter::EmitFloatConversionCheck(
1058 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1059 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1060 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1064 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1065 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1066 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1067 using llvm::APFloat;
1070 llvm::Value *Check =
nullptr;
1071 const llvm::fltSemantics &SrcSema =
1081 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1082 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1083 APFloat::opOverflow)
1086 MinSrc = APFloat::getInf(SrcSema,
true);
1090 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1093 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1094 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1095 APFloat::opOverflow)
1098 MaxSrc = APFloat::getInf(SrcSema,
false);
1102 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1107 const llvm::fltSemantics &Sema =
1110 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1111 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1115 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1117 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1118 Check = Builder.CreateAnd(GE, LE);
1123 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1129static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1130 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1133 llvm::Type *SrcTy = Src->
getType();
1134 llvm::Type *DstTy = Dst->
getType();
1139 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1141 "non-integer llvm type");
1148 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1150 if (!SrcSigned && !DstSigned) {
1151 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1152 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1154 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1155 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1158 llvm::Value *Check =
nullptr;
1160 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1162 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1164 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1172void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1173 Value *Dst, QualType DstType,
1175 bool OBTrapInvolved) {
1176 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1186 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1187 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1189 if (SrcBits <= DstBits)
1192 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1199 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1200 (!SrcSigned && DstSigned))
1203 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1204 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1207 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1212 SanitizerDebugLocation SanScope(
1214 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1215 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1231 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1239 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1240 if (OBT->isWrapKind())
1243 if (ignoredBySanitizer && !OBTrapInvolved)
1246 llvm::Constant *StaticArgs[] = {
1249 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1250 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1252 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1259 llvm::Type *VTy =
V->getType();
1262 return llvm::ConstantInt::getFalse(VTy->getContext());
1264 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1265 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1266 llvm::Twine(Name) +
"." +
V->getName() +
1267 ".negativitycheck");
1272static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1273 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1276 llvm::Type *SrcTy = Src->
getType();
1277 llvm::Type *DstTy = Dst->
getType();
1280 "non-integer llvm type");
1286 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1287 unsigned DstBits = DstTy->getScalarSizeInBits();
1291 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1292 "either the widths should be different, or the signednesses.");
1295 llvm::Value *SrcIsNegative =
1298 llvm::Value *DstIsNegative =
1304 llvm::Value *Check =
nullptr;
1305 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1307 return std::make_pair(
1308 ScalarExprEmitter::ICCK_IntegerSignChange,
1309 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1312void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1313 Value *Dst, QualType DstType,
1315 bool OBTrapInvolved) {
1316 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1320 llvm::Type *SrcTy = Src->
getType();
1321 llvm::Type *DstTy = Dst->
getType();
1331 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1332 unsigned DstBits = DstTy->getScalarSizeInBits();
1339 if (SrcSigned == DstSigned && SrcBits == DstBits)
1343 if (!SrcSigned && !DstSigned)
1348 if ((DstBits > SrcBits) && DstSigned)
1350 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1351 (SrcBits > DstBits) && SrcSigned) {
1360 if (!OBTrapInvolved) {
1363 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1367 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1372 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1373 SanitizerDebugLocation SanScope(
1375 {SanitizerKind::SO_ImplicitIntegerSignChange,
1376 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1377 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1380 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1381 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1385 ImplicitConversionCheckKind CheckKind;
1386 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1393 CheckKind = Check.first;
1394 Checks.emplace_back(Check.second);
1396 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1397 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1403 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1404 Checks.emplace_back(Check.second);
1408 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1409 if (OBTrapInvolved) {
1410 llvm::Value *Combined = Check.second.first;
1411 for (
const auto &
C : Checks)
1412 Combined = Builder.CreateAnd(Combined,
C.first);
1418 llvm::Constant *StaticArgs[] = {
1421 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1422 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1424 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1429static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1430 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1436 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1437 if (!SrcSigned && !DstSigned)
1438 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1440 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1442 llvm::Value *Check =
nullptr;
1444 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1446 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1449 return std::make_pair(
1451 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1456static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1457 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1461 llvm::Value *SrcIsNegative =
1464 llvm::Value *DstIsNegative =
1470 llvm::Value *Check =
nullptr;
1472 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1474 return std::make_pair(
1475 ScalarExprEmitter::ICCK_IntegerSignChange,
1476 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1484 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1502 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1503 unsigned DstBits = Info.
Size;
1508 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1510 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1512 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1513 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1517 bool EmitTruncation = DstBits < SrcBits;
1521 bool EmitTruncationFromUnsignedToSigned =
1522 EmitTruncation && DstSigned && !SrcSigned;
1524 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1525 bool BothUnsigned = !SrcSigned && !DstSigned;
1526 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1533 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1538 else if (EmitSignChange) {
1539 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1540 "either the widths should be different, or the signednesses.");
1546 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1547 if (EmitTruncationFromUnsignedToSigned)
1548 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1550 llvm::Constant *StaticArgs[] = {
1553 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1554 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1556 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1560 QualType DstType, llvm::Type *SrcTy,
1562 ScalarConversionOpts Opts) {
1564 llvm::Type *SrcElementTy;
1565 llvm::Type *DstElementTy;
1575 "cannot cast between matrix and non-matrix types");
1576 SrcElementTy = SrcTy;
1577 DstElementTy = DstTy;
1578 SrcElementType = SrcType;
1579 DstElementType = DstType;
1584 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1589 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1591 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1592 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1596 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1603 llvm::Intrinsic::ID IID =
1604 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1605 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1609 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1610 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1613 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1614 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1615 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1617 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1618 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1619 return Builder.CreateFPExt(Src, DstTy,
"conv");
1624Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1627 ScalarConversionOpts Opts) {
1642 return Builder.CreateIsNotNull(Src,
"tobool");
1645 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1648 "Unhandled scalar conversion from a fixed point type to another type.");
1652 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1655 "Unhandled scalar conversion to a fixed point type from another type.");
1658 QualType NoncanonicalSrcType = SrcType;
1659 QualType NoncanonicalDstType = DstType;
1663 if (SrcType == DstType)
return Src;
1667 llvm::Value *OrigSrc = Src;
1668 QualType OrigSrcType = SrcType;
1669 llvm::Type *SrcTy = Src->
getType();
1673 return EmitConversionToBool(Src, SrcType);
1675 llvm::Type *DstTy = ConvertType(DstType);
1684 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1685 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1686 bool OBTrapInvolved =
1687 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1688 bool OBWrapInvolved =
1689 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1694 if (DstTy->isFloatingPointTy()) {
1697 return Builder.CreateFPExt(BitCast, DstTy,
"conv");
1706 Src = Builder.CreateBitCast(Src, CGF.
CGM.
HalfTy);
1709 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1716 if (SrcTy == DstTy) {
1717 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1718 (OBTrapInvolved && !OBWrapInvolved))
1719 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1720 NoncanonicalDstType, Loc, OBTrapInvolved);
1728 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1733 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1738 llvm::Value* IntResult =
1739 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1741 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1747 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1754 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1756 "Splatted expr doesn't match with vector element type?");
1760 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1764 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1768 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1769 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1770 if (SrcSize == DstSize)
1771 return Builder.CreateBitCast(Src, DstTy,
"conv");
1784 assert(((SrcElementTy->isIntegerTy() &&
1785 DstElementTy->isIntegerTy()) ||
1786 (SrcElementTy->isFloatingPointTy() &&
1787 DstElementTy->isFloatingPointTy())) &&
1788 "unexpected conversion between a floating-point vector and an "
1792 if (SrcElementTy->isIntegerTy())
1793 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1796 if (SrcSize > DstSize)
1797 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1800 return Builder.CreateFPExt(Src, DstTy,
"conv");
1804 Value *Res =
nullptr;
1805 llvm::Type *ResTy = DstTy;
1812 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1814 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1820 if (SrcTy->isFloatingPointTy()) {
1829 assert(DstTy->isIntegerTy(16) &&
1831 "Only half FP requires extra conversion");
1832 return Builder.CreateBitCast(Res, DstTy);
1838 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1840 if (DstTy != ResTy) {
1841 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1844 assert(ResTy->isIntegerTy(16) &&
1846 "Only half FP requires extra conversion");
1847 Res = Builder.CreateBitCast(Res, ResTy);
1851 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1852 !OBWrapInvolved && !Opts.PatternExcluded)
1853 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1854 NoncanonicalDstType, Loc, OBTrapInvolved);
1856 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1857 (OBTrapInvolved && !OBWrapInvolved))
1858 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1859 NoncanonicalDstType, Loc, OBTrapInvolved);
1864Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1866 SourceLocation Loc) {
1867 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1870 Result = FPBuilder.CreateFloatingToFixed(Src,
1873 Result = FPBuilder.CreateFixedToFloating(Src,
1875 ConvertType(DstTy));
1881 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1882 DstFPSema.getWidth(),
1883 DstFPSema.isSigned());
1885 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1888 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1895Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1897 SourceLocation Loc) {
1899 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1904 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1905 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1906 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1913 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1916Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1924void ScalarExprEmitter::EmitBinOpCheck(
1925 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1926 const BinOpInfo &Info) {
1929 SmallVector<llvm::Constant *, 4> StaticData;
1930 SmallVector<llvm::Value *, 2> DynamicData;
1938 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1939 if (UO && UO->
getOpcode() == UO_Minus) {
1940 Check = SanitizerHandler::NegateOverflow;
1942 DynamicData.push_back(Info.RHS);
1946 Check = SanitizerHandler::ShiftOutOfBounds;
1948 StaticData.push_back(
1950 StaticData.push_back(
1952 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1954 Check = SanitizerHandler::DivremOverflow;
1958 int ArithOverflowKind = 0;
1961 Check = SanitizerHandler::AddOverflow;
1962 ArithOverflowKind = diag::UBSanArithKind::Add;
1966 Check = SanitizerHandler::SubOverflow;
1967 ArithOverflowKind = diag::UBSanArithKind::Sub;
1971 Check = SanitizerHandler::MulOverflow;
1972 ArithOverflowKind = diag::UBSanArithKind::Mul;
1976 llvm_unreachable(
"unexpected opcode for bin op check");
1980 SanitizerKind::UnsignedIntegerOverflow) ||
1982 SanitizerKind::SignedIntegerOverflow)) {
1986 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1990 DynamicData.push_back(Info.LHS);
1991 DynamicData.push_back(Info.RHS);
1994 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
2001Value *ScalarExprEmitter::VisitExpr(Expr *E) {
2009ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
2011 unsigned AddrSpace =
2013 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
2016 llvm::Type *ExprTy = ConvertType(E->
getType());
2017 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2021Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2023 auto It = E->
begin();
2024 return Builder.getInt((*It)->getValue());
2027Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2035 unsigned LHSElts = LTy->getNumElements();
2043 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2044 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2052 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2053 MTy->getNumElements());
2054 Value* NewV = llvm::PoisonValue::get(RTy);
2055 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2056 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2057 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2059 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2060 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2068 SmallVector<int, 32> Indices;
2072 if (Idx.isSigned() && Idx.isAllOnes())
2073 Indices.push_back(-1);
2075 Indices.push_back(Idx.getZExtValue());
2078 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2081Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2089 if (SrcType == DstType)
return Src;
2092 "ConvertVector source type must be a vector");
2094 "ConvertVector destination type must be a vector");
2096 llvm::Type *SrcTy = Src->
getType();
2097 llvm::Type *DstTy = ConvertType(DstType);
2103 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2104 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2106 assert(SrcTy->isVectorTy() &&
2107 "ConvertVector source IR type must be a vector");
2108 assert(DstTy->isVectorTy() &&
2109 "ConvertVector destination IR type must be a vector");
2114 if (DstEltType->isBooleanType()) {
2115 assert((SrcEltTy->isFloatingPointTy() ||
2118 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2119 if (SrcEltTy->isFloatingPointTy()) {
2120 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2121 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2123 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2128 Value *Res =
nullptr;
2133 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2135 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2137 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2139 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2142 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2143 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2144 if (DstEltType->isSignedIntegerOrEnumerationType())
2145 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2147 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2149 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2150 "Unknown real conversion");
2151 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2152 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2153 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2155 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2161Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2170 return Builder.getInt(
Value);
2174 llvm::Value *
Result = EmitLoadOfLValue(E);
2180 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2181 if (llvm::GetElementPtrInst *GEP =
2182 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2183 if (llvm::Instruction *
Pointer =
2184 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2196Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2197 TestAndClearIgnoreResultAssign();
2205 return EmitLoadOfLValue(E);
2213 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2216 Value *
Ret = Builder.CreateExtractElement(Base, Idx,
"vecext");
2220 Ret = Builder.CreateInsertElement(
2221 llvm::PoisonValue::get(llvm::FixedVectorType::get(CGF.
Int8Ty, 1)), Ret,
2227Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2228 MatrixSingleSubscriptExpr *E) {
2229 TestAndClearIgnoreResultAssign();
2232 unsigned NumRows = MatrixTy->getNumRows();
2233 unsigned NumColumns = MatrixTy->getNumColumns();
2237 llvm::MatrixBuilder MB(Builder);
2241 MB.CreateIndexAssumption(RowIdx, NumRows);
2245 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2246 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2248 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2249 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2250 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2251 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2252 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2253 IsMatrixRowMajor,
"matrix_row_idx");
2255 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2256 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2257 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2263Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2264 TestAndClearIgnoreResultAssign();
2272 llvm::MatrixBuilder MB(Builder);
2275 unsigned NumCols = MatrixTy->getNumColumns();
2276 unsigned NumRows = MatrixTy->getNumRows();
2277 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2278 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2279 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2282 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2287 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2292 int MV = SVI->getMaskValue(Idx);
2299 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2300 "Index operand too large for shufflevector mask!");
2301 return C->getZExtValue();
2304Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2305 bool Ignore = TestAndClearIgnoreResultAssign();
2308 assert((Ignore ==
false ||
2310 "init list ignored");
2327 llvm::VectorType *VType =
2328 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2331 if (NumInitElements == 0) {
2333 return EmitNullValue(E->
getType());
2340 if (NumInitElements == 0) {
2342 return EmitNullValue(E->
getType());
2345 if (NumInitElements == 1) {
2346 Expr *InitVector = E->
getInit(0);
2351 return Visit(InitVector);
2354 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2361 const ConstantMatrixType *ColMajorMT =
nullptr;
2362 if (
const auto *MT = E->
getType()->
getAs<ConstantMatrixType>();
2363 MT && CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2364 LangOptions::MatrixMemoryLayout::MatrixColMajor)
2372 unsigned CurIdx = 0;
2373 bool VIsPoisonShuffle =
false;
2374 llvm::Value *
V = llvm::PoisonValue::get(VType);
2375 for (
unsigned i = 0; i != NumInitElements; ++i) {
2378 SmallVector<int, 16> Args;
2380 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2390 ->getNumElements() == ResElts) {
2392 Value *LHS =
nullptr, *RHS =
nullptr;
2397 Args.resize(ResElts, -1);
2399 LHS = EI->getVectorOperand();
2401 VIsPoisonShuffle =
true;
2402 }
else if (VIsPoisonShuffle) {
2405 for (
unsigned j = 0; j != CurIdx; ++j)
2407 Args.push_back(ResElts +
C->getZExtValue());
2408 Args.resize(ResElts, -1);
2411 RHS = EI->getVectorOperand();
2412 VIsPoisonShuffle =
false;
2414 if (!Args.empty()) {
2415 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2421 unsigned InsertIdx =
2425 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(InsertIdx),
2427 VIsPoisonShuffle =
false;
2437 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2440 Value *SVOp = SVI->getOperand(0);
2443 if (OpTy->getNumElements() == ResElts) {
2444 for (
unsigned j = 0; j != CurIdx; ++j) {
2447 if (VIsPoisonShuffle) {
2453 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2455 Args.resize(ResElts, -1);
2457 if (VIsPoisonShuffle)
2467 for (
unsigned j = 0; j != InitElts; ++j)
2469 Args.resize(ResElts, -1);
2470 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2473 for (
unsigned j = 0; j != CurIdx; ++j)
2475 for (
unsigned j = 0; j != InitElts; ++j)
2476 Args.push_back(j + Offset);
2477 Args.resize(ResElts, -1);
2484 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2491 llvm::Type *EltTy = VType->getElementType();
2494 for (; CurIdx < ResElts; ++CurIdx) {
2495 unsigned InsertIdx =
2498 Value *Idx = Builder.getInt32(InsertIdx);
2499 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2500 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2513 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2517 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2520 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2539 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2543 if (
const auto *CE = dyn_cast<CastExpr>(E))
2544 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2545 CE->getCastKind() == CK_ArrayToPointerDecay)
2556 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2566 if (ICE->isGLValue())
2581 assert(LoadList.size() >= VecTy->getNumElements() &&
2582 "Flattened type on RHS must have the same number or more elements "
2583 "than vector on LHS.");
2587 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2590 "All flattened source values should be scalars.");
2593 VecTy->getElementType(), Loc);
2594 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2599 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2600 "Flattened type on RHS must have the same number or more elements "
2601 "than vector on LHS.");
2603 bool IsRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
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());
3183 bool IsRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
3184 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
3185 for (
unsigned R = 0;
R < NumRows;
R++)
3186 for (
unsigned C = 0;
C < NumCols;
C++)
3187 Mask[MatTy->getFlattenedIndex(R,
C, IsRowMajor)] =
3188 SrcMatTy->getFlattenedIndex(R,
C, IsRowMajor);
3190 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3192 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3193 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3195 case CK_HLSLElementwiseCast: {
3215 llvm_unreachable(
"unknown scalar cast");
3218Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3219 CodeGenFunction::StmtExprEvaluation eval(CGF);
3228Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3229 CodeGenFunction::RunCleanupsScope Scope(CGF);
3233 Scope.ForceCleanup({&
V});
3242 llvm::Value *InVal,
bool IsInc,
3246 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3248 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3249 BinOp.FPFeatures = FPFeatures;
3254llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3255 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3258 llvm::Value *Amount =
3259 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3260 StringRef Name = IsInc ?
"inc" :
"dec";
3264 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3265 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3267 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3268 case LangOptions::OB_Wrap:
3269 return Builder.CreateAdd(InVal, Amount, Name);
3270 case LangOptions::OB_SignedAndDefined:
3272 return Builder.CreateAdd(InVal, Amount, Name);
3274 case LangOptions::OB_Unset:
3276 return Builder.CreateAdd(InVal, Amount, Name);
3278 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3279 : Builder.CreateAdd(InVal, Amount, Name);
3281 case LangOptions::OB_Trap:
3283 return Builder.CreateAdd(InVal, Amount, Name);
3286 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3287 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3288 : Builder.CreateAdd(InVal, Amount, Name);
3289 return EmitOverflowCheckedBinOp(Info);
3291 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3296class OMPLastprivateConditionalUpdateRAII {
3298 CodeGenFunction &CGF;
3299 const UnaryOperator *E;
3302 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3303 const UnaryOperator *E)
3305 ~OMPLastprivateConditionalUpdateRAII() {
3314ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3315 bool isInc,
bool isPre) {
3317 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3319 llvm::PHINode *atomicPHI =
nullptr;
3323 QualType SrcType = E->
getType();
3325 int amount = (isInc ? 1 : -1);
3326 bool isSubtraction = !isInc;
3328 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3329 type = atomicTy->getValueType();
3330 if (isInc &&
type->isBooleanType()) {
3333 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3334 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3335 return Builder.getTrue();
3339 return Builder.CreateAtomicRMW(
3340 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3341 llvm::AtomicOrdering::SequentiallyConsistent);
3346 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3347 !(
type->isUnsignedIntegerType() &&
3348 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3350 LangOptions::SOB_Trapping) {
3351 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3352 llvm::AtomicRMWInst::Sub;
3353 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3354 llvm::Instruction::Sub;
3356 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3358 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3359 llvm::AtomicOrdering::SequentiallyConsistent);
3360 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3364 if (
type->isFloatingType()) {
3365 llvm::Type *Ty = ConvertType(
type);
3366 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3367 llvm::AtomicRMWInst::BinOp aop =
3368 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3369 llvm::Instruction::BinaryOps op =
3370 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3371 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3372 llvm::AtomicRMWInst *old =
3374 llvm::AtomicOrdering::SequentiallyConsistent);
3376 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3379 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3382 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3385 Builder.CreateBr(opBB);
3386 Builder.SetInsertPoint(opBB);
3387 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3388 atomicPHI->addIncoming(value, startBB);
3391 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3402 if (isInc &&
type->isBooleanType()) {
3403 value = Builder.getTrue();
3406 }
else if (
type->isIntegerType()) {
3407 QualType promotedType;
3408 bool canPerformLossyDemotionCheck =
false;
3412 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3413 canPerformLossyDemotionCheck =
true;
3414 canPerformLossyDemotionCheck &=
3417 canPerformLossyDemotionCheck &=
3419 type, promotedType);
3420 assert((!canPerformLossyDemotionCheck ||
3421 type->isSignedIntegerOrEnumerationType() ||
3423 ConvertType(
type)->getScalarSizeInBits() ==
3424 ConvertType(promotedType)->getScalarSizeInBits()) &&
3425 "The following check expects that if we do promotion to different "
3426 "underlying canonical type, at least one of the types (either "
3427 "base or promoted) will be signed, or the bitwidths will match.");
3430 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3431 SanitizerKind::ImplicitBitfieldConversion) &&
3432 canPerformLossyDemotionCheck) {
3446 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3447 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3448 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3452 ScalarConversionOpts Opts;
3453 if (!LV.isBitField())
3454 Opts = ScalarConversionOpts(CGF.
SanOpts);
3455 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3457 SrcType = promotedType;
3461 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3467 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3468 type->isUnsignedIntegerType()) {
3469 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3474 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3475 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3479 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3480 QualType
type = ptr->getPointeeType();
3483 if (
const VariableArrayType *vla
3486 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3489 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3492 elemTy, value, numElts,
false, isSubtraction,
3496 }
else if (
type->isFunctionType()) {
3497 llvm::Value *amt = Builder.getInt32(amount);
3500 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3504 false, isSubtraction,
3509 llvm::Value *amt = Builder.getInt32(amount);
3512 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3515 elemTy, value, amt,
false, isSubtraction,
3520 }
else if (
type->isVectorType()) {
3521 if (
type->hasIntegerRepresentation()) {
3522 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3524 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3526 value = Builder.CreateFAdd(
3528 llvm::ConstantFP::get(value->getType(), amount),
3529 isInc ?
"inc" :
"dec");
3533 }
else if (
type->isRealFloatingType()) {
3536 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3542 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3545 if (value->getType()->isFloatTy())
3546 amt = llvm::ConstantFP::get(VMContext,
3547 llvm::APFloat(
static_cast<float>(amount)));
3548 else if (value->getType()->isDoubleTy())
3549 amt = llvm::ConstantFP::get(VMContext,
3550 llvm::APFloat(
static_cast<double>(amount)));
3554 llvm::APFloat F(
static_cast<float>(amount));
3556 const llvm::fltSemantics *FS;
3559 if (value->getType()->isFP128Ty())
3561 else if (value->getType()->isHalfTy())
3563 else if (value->getType()->isBFloatTy())
3565 else if (value->getType()->isPPC_FP128Ty())
3569 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3570 amt = llvm::ConstantFP::get(VMContext, F);
3572 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3575 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3576 value = Builder.CreateBitCast(value, input->getType());
3580 }
else if (
type->isFixedPointType()) {
3587 Info.Opcode = isInc ? BO_Add : BO_Sub;
3589 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3592 if (
type->isSignedFixedPointType()) {
3593 Info.Opcode = isInc ? BO_Sub : BO_Add;
3594 Info.RHS = Builder.CreateNeg(Info.RHS);
3599 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3601 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3602 value = EmitFixedPointBinOp(Info);
3606 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3609 if (!isInc) size = -size;
3610 llvm::Value *sizeValue =
3611 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3614 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3617 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3619 value = Builder.CreateBitCast(value, input->getType());
3623 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3628 llvm::Value *
success = Pair.second;
3629 atomicPHI->addIncoming(old, curBlock);
3630 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3631 Builder.SetInsertPoint(contBB);
3632 return isPre ? value : input;
3636 if (LV.isBitField()) {
3646 return isPre ? value : input;
3650Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3651 QualType PromotionType) {
3652 QualType promotionTy = PromotionType.
isNull()
3655 Value *result = VisitPlus(E, promotionTy);
3656 if (result && !promotionTy.
isNull())
3657 result = EmitUnPromotedValue(result, E->
getType());
3661Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3662 QualType PromotionType) {
3664 TestAndClearIgnoreResultAssign();
3665 if (!PromotionType.
isNull())
3670Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3671 QualType PromotionType) {
3672 QualType promotionTy = PromotionType.
isNull()
3675 Value *result = VisitMinus(E, promotionTy);
3676 if (result && !promotionTy.
isNull())
3677 result = EmitUnPromotedValue(result, E->
getType());
3681Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3682 QualType PromotionType) {
3683 TestAndClearIgnoreResultAssign();
3685 if (!PromotionType.
isNull())
3691 if (Op->
getType()->isFPOrFPVectorTy())
3692 return Builder.CreateFNeg(Op,
"fneg");
3697 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3699 BinOp.Opcode = BO_Sub;
3702 return EmitSub(BinOp);
3705Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3706 TestAndClearIgnoreResultAssign();
3708 return Builder.CreateNot(Op,
"not");
3711Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3715 VectorKind::Generic) {
3719 if (Oper->
getType()->isFPOrFPVectorTy()) {
3720 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3722 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3724 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3725 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3734 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3737 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3740Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3742 Expr::EvalResult EVResult;
3745 return Builder.getInt(
Value);
3750 llvm::Type* ResultType = ConvertType(E->
getType());
3751 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3753 for (
unsigned i = 0; i != n; ++i) {
3755 llvm::Value *Offset =
nullptr;
3762 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3769 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3773 Offset = Builder.CreateMul(Idx, ElemSize);
3778 FieldDecl *MemberDecl = ON.
getField();
3788 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3791 CurrentType = MemberDecl->
getType();
3796 llvm_unreachable(
"dependent __builtin_offsetof");
3813 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3825ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3826 const UnaryExprOrTypeTraitExpr *E) {
3829 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3830 if (
const VariableArrayType *VAT =
3835 bool EvaluateExtent =
true;
3836 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3838 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3840 if (EvaluateExtent) {
3851 if (Kind == UETT_CountOf)
3860 if (!eltSize.
isOne())
3863 return VlaSize.NumElts;
3866 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3872 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3873 }
else if (E->
getKind() == UETT_VectorElements) {
3875 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3883Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3884 QualType PromotionType) {
3885 QualType promotionTy = PromotionType.
isNull()
3888 Value *result = VisitReal(E, promotionTy);
3889 if (result && !promotionTy.
isNull())
3890 result = EmitUnPromotedValue(result, E->
getType());
3894Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3895 QualType PromotionType) {
3902 if (!PromotionType.
isNull()) {
3904 Op, IgnoreResultAssign,
true);
3919 if (!PromotionType.
isNull())
3924Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3925 QualType PromotionType) {
3926 QualType promotionTy = PromotionType.
isNull()
3929 Value *result = VisitImag(E, promotionTy);
3930 if (result && !promotionTy.
isNull())
3931 result = EmitUnPromotedValue(result, E->
getType());
3935Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3936 QualType PromotionType) {
3943 if (!PromotionType.
isNull()) {
3945 Op,
true, IgnoreResultAssign);
3949 return result.second
3965 else if (!PromotionType.
isNull())
3969 if (!PromotionType.
isNull())
3970 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3971 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3978Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3979 QualType PromotionType) {
3980 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3983Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3984 QualType ExprType) {
3985 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3988Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3990 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3992#define HANDLE_BINOP(OP) \
3994 return Emit##OP(EmitBinOps(BO, PromotionType));
4003 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
4006 return VisitImag(UO, PromotionType);
4008 return VisitReal(UO, PromotionType);
4010 return VisitMinus(UO, PromotionType);
4012 return VisitPlus(UO, PromotionType);
4017 auto result = Visit(
const_cast<Expr *
>(E));
4019 if (!PromotionType.
isNull())
4020 return EmitPromotedValue(result, PromotionType);
4022 return EmitUnPromotedValue(result, E->
getType());
4027BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4028 QualType PromotionType) {
4029 TestAndClearIgnoreResultAssign();
4033 if (!PromotionType.
isNull())
4034 Result.Ty = PromotionType;
4043LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4044 const CompoundAssignOperator *E,
4045 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4056 QualType PromotionTypeCR;
4058 if (PromotionTypeCR.
isNull())
4061 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4062 if (!PromotionTypeRHS.
isNull())
4065 OpInfo.RHS = Visit(E->
getRHS());
4066 OpInfo.Ty = PromotionTypeCR;
4073 llvm::PHINode *atomicPHI =
nullptr;
4074 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4075 QualType
type = atomicTy->getValueType();
4076 if (!
type->isBooleanType() &&
type->isIntegerType() &&
4077 !(
type->isUnsignedIntegerType() &&
4078 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4080 LangOptions::SOB_Trapping) {
4081 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4082 llvm::Instruction::BinaryOps Op;
4083 switch (OpInfo.Opcode) {
4085 case BO_MulAssign:
case BO_DivAssign:
4091 AtomicOp = llvm::AtomicRMWInst::Add;
4092 Op = llvm::Instruction::Add;
4095 AtomicOp = llvm::AtomicRMWInst::Sub;
4096 Op = llvm::Instruction::Sub;
4099 AtomicOp = llvm::AtomicRMWInst::And;
4100 Op = llvm::Instruction::And;
4103 AtomicOp = llvm::AtomicRMWInst::Xor;
4104 Op = llvm::Instruction::Xor;
4107 AtomicOp = llvm::AtomicRMWInst::Or;
4108 Op = llvm::Instruction::Or;
4111 llvm_unreachable(
"Invalid compound assignment type");
4113 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4115 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4119 llvm::AtomicRMWInst *OldVal =
4124 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4130 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4132 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4134 Builder.CreateBr(opBB);
4135 Builder.SetInsertPoint(opBB);
4136 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4137 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4138 OpInfo.LHS = atomicPHI;
4141 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4143 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4145 if (!PromotionTypeLHS.
isNull())
4146 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4149 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4160 if (LHSLV.isBitField()) {
4162 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4163 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4165 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4166 Loc, ScalarConversionOpts(CGF.
SanOpts));
4168 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4169 ScalarConversionOpts(CGF.
SanOpts));
4173 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4177 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4178 llvm::Value *
success = Pair.second;
4179 atomicPHI->addIncoming(old, curBlock);
4180 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4181 Builder.SetInsertPoint(contBB);
4189 if (LHSLV.isBitField()) {
4205Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4206 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4207 bool Ignore = TestAndClearIgnoreResultAssign();
4208 Value *RHS =
nullptr;
4209 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4220 if (!LHS.isVolatileQualified())
4224 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4227void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4228 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4229 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4232 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4233 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4234 SanitizerKind::SO_IntegerDivideByZero));
4238 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4239 Ops.Ty->hasSignedIntegerRepresentation() &&
4241 Ops.mayHaveIntegerOverflow() &&
4243 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4246 llvm::Value *IntMin =
4247 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4248 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4250 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4251 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4252 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4254 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4257 if (Checks.size() > 0)
4258 EmitBinOpCheck(Checks, Ops);
4261Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4263 SanitizerDebugLocation SanScope(&CGF,
4264 {SanitizerKind::SO_IntegerDivideByZero,
4265 SanitizerKind::SO_SignedIntegerOverflow,
4266 SanitizerKind::SO_FloatDivideByZero},
4267 SanitizerHandler::DivremOverflow);
4268 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4269 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4270 Ops.Ty->isIntegerType() &&
4271 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4272 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4273 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4274 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4275 Ops.Ty->isRealFloatingType() &&
4276 Ops.mayHaveFloatDivisionByZero()) {
4277 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4278 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4280 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4284 if (Ops.Ty->isConstantMatrixType()) {
4285 llvm::MatrixBuilder MB(Builder);
4292 "first operand must be a matrix");
4294 "second operand must be an arithmetic type");
4295 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4296 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4297 Ops.Ty->hasUnsignedIntegerRepresentation());
4300 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4302 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4303 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4307 else if (Ops.isFixedPointOp())
4308 return EmitFixedPointBinOp(Ops);
4309 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4310 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4312 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4315Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4317 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4318 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4319 Ops.Ty->isIntegerType() &&
4320 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4321 SanitizerDebugLocation SanScope(&CGF,
4322 {SanitizerKind::SO_IntegerDivideByZero,
4323 SanitizerKind::SO_SignedIntegerOverflow},
4324 SanitizerHandler::DivremOverflow);
4325 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4326 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4329 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4330 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4332 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4333 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4335 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4338Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4343 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4344 switch (Ops.Opcode) {
4348 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4349 llvm::Intrinsic::uadd_with_overflow;
4350 OverflowKind = SanitizerHandler::AddOverflow;
4355 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4356 llvm::Intrinsic::usub_with_overflow;
4357 OverflowKind = SanitizerHandler::SubOverflow;
4362 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4363 llvm::Intrinsic::umul_with_overflow;
4364 OverflowKind = SanitizerHandler::MulOverflow;
4367 llvm_unreachable(
"Unsupported operation for overflow detection");
4373 SanitizerDebugLocation SanScope(&CGF,
4374 {SanitizerKind::SO_SignedIntegerOverflow,
4375 SanitizerKind::SO_UnsignedIntegerOverflow},
4381 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4382 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4383 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4386 const std::string *handlerName =
4388 if (handlerName->empty()) {
4394 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4395 llvm::Value *NotOf = Builder.CreateNot(overflow);
4397 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4400 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4403 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4404 llvm::Value *NotOf = Builder.CreateNot(overflow);
4406 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4409 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4414 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4415 llvm::BasicBlock *continueBB =
4419 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4423 Builder.SetInsertPoint(overflowBB);
4426 llvm::Type *Int8Ty = CGF.
Int8Ty;
4427 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4428 llvm::FunctionType *handlerTy =
4429 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4430 llvm::FunctionCallee handler =
4435 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4436 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4440 llvm::Value *handlerArgs[] = {
4443 Builder.getInt8(OpID),
4446 llvm::Value *handlerResult =
4450 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4451 Builder.CreateBr(continueBB);
4453 Builder.SetInsertPoint(continueBB);
4454 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4455 phi->addIncoming(result, initialBB);
4456 phi->addIncoming(handlerResult, overflowBB);
4465 bool isSubtraction) {
4470 Value *pointer = op.LHS;
4471 Expr *pointerOperand =
expr->getLHS();
4473 Expr *indexOperand =
expr->getRHS();
4476 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4477 std::swap(pointer,
index);
4478 std::swap(pointerOperand, indexOperand);
4482 index, isSubtraction);
4488 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4492 auto &DL =
CGM.getDataLayout();
4515 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4517 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4518 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4519 PtrTy->getPointerAddressSpace()))
4522 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4523 auto CheckHandler = SanitizerHandler::PointerOverflow;
4525 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4527 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4528 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4530 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4531 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4536 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4547 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4557 llvm::Value *objectSize =
4563 return Builder.CreateBitCast(result, pointer->getType());
4568 getContext().getAsVariableArrayType(elementType)) {
4570 llvm::Value *numElements =
getVLASize(vla).NumElts;
4579 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4599 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4612 bool negMul,
bool negAdd) {
4613 Value *MulOp0 = MulOp->getOperand(0);
4614 Value *MulOp1 = MulOp->getOperand(1);
4616 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4618 Addend = Builder.CreateFNeg(Addend,
"neg");
4620 Value *FMulAdd =
nullptr;
4621 if (Builder.getIsFPConstrained()) {
4623 "Only constrained operation should be created when Builder is in FP "
4624 "constrained mode");
4625 FMulAdd = Builder.CreateConstrainedFPCall(
4626 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4628 {MulOp0, MulOp1, Addend});
4630 FMulAdd = Builder.CreateCall(
4632 {MulOp0, MulOp1, Addend});
4634 MulOp->eraseFromParent();
4649 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4650 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4651 "Only fadd/fsub can be the root of an fmuladd.");
4654 if (!op.FPFeatures.allowFPContractWithinStatement())
4657 Value *LHS = op.LHS;
4658 Value *RHS = op.RHS;
4662 bool NegLHS =
false;
4663 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4664 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4665 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4666 LHS = LHSUnOp->getOperand(0);
4671 bool NegRHS =
false;
4672 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4673 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4674 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4675 RHS = RHSUnOp->getOperand(0);
4683 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4684 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4685 (LHSBinOp->use_empty() || NegLHS)) {
4689 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4692 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4693 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4694 (RHSBinOp->use_empty() || NegRHS)) {
4698 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4702 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4703 if (LHSBinOp->getIntrinsicID() ==
4704 llvm::Intrinsic::experimental_constrained_fmul &&
4705 (LHSBinOp->use_empty() || NegLHS)) {
4709 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4712 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4713 if (RHSBinOp->getIntrinsicID() ==
4714 llvm::Intrinsic::experimental_constrained_fmul &&
4715 (RHSBinOp->use_empty() || NegRHS)) {
4719 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4726Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4727 if (op.LHS->getType()->isPointerTy() ||
4728 op.RHS->getType()->isPointerTy())
4731 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4732 op.Ty->isUnsignedIntegerType()) {
4733 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4735 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4736 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4737 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4738 case LangOptions::OB_Wrap:
4739 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4740 case LangOptions::OB_SignedAndDefined:
4742 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4744 case LangOptions::OB_Unset:
4746 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4747 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4749 case LangOptions::OB_Trap:
4750 if (CanElideOverflowCheck(CGF.
getContext(), op))
4751 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4752 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4753 return EmitOverflowCheckedBinOp(op);
4758 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4759 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4765 if (op.Ty->isConstantMatrixType()) {
4766 llvm::MatrixBuilder MB(Builder);
4767 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4768 return MB.CreateAdd(op.LHS, op.RHS);
4771 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4772 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4773 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4776 if (op.isFixedPointOp())
4777 return EmitFixedPointBinOp(op);
4779 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4784Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4786 using llvm::ConstantInt;
4792 QualType ResultTy = op.Ty;
4793 QualType LHSTy, RHSTy;
4794 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4795 RHSTy = BinOp->getRHS()->getType();
4796 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4801 LHSTy = CAO->getComputationLHSType();
4802 ResultTy = CAO->getComputationResultType();
4804 LHSTy = BinOp->getLHS()->getType();
4805 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4806 LHSTy = UnOp->getSubExpr()->getType();
4807 RHSTy = UnOp->getSubExpr()->getType();
4810 Value *LHS = op.LHS;
4811 Value *RHS = op.RHS;
4816 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4820 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4821 switch (op.Opcode) {
4824 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4828 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4832 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4836 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4840 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4844 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4847 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4849 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4851 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4853 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4858 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4860 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4864 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4877 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4883 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4888Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4890 if (!op.LHS->getType()->isPointerTy()) {
4891 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4892 op.Ty->isUnsignedIntegerType()) {
4893 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4895 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4896 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4897 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4898 case LangOptions::OB_Wrap:
4899 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4900 case LangOptions::OB_SignedAndDefined:
4902 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4904 case LangOptions::OB_Unset:
4906 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4907 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4909 case LangOptions::OB_Trap:
4910 if (CanElideOverflowCheck(CGF.
getContext(), op))
4911 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4912 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4913 return EmitOverflowCheckedBinOp(op);
4918 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4919 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4925 if (op.Ty->isConstantMatrixType()) {
4926 llvm::MatrixBuilder MB(Builder);
4927 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4928 return MB.CreateSub(op.LHS, op.RHS);
4931 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4932 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4933 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4936 if (op.isFixedPointOp())
4937 return EmitFixedPointBinOp(op);
4939 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4944 if (!op.RHS->getType()->isPointerTy())
4951 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4953 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4954 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4958 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4960 llvm::Value *divisor =
nullptr;
4963 if (
const VariableArrayType *vla
4966 elementType = VlaSize.Type;
4967 divisor = VlaSize.NumElts;
4971 if (!eltSize.
isOne())
4978 CharUnits elementSize;
4987 if (elementSize.
isOne())
4996 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4999Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
5001 llvm::IntegerType *Ty;
5002 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5010 llvm::Type *RHSTy = RHS->
getType();
5011 llvm::APInt RHSMax =
5012 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5013 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5014 if (RHSMax.ult(Ty->getBitWidth()))
5015 return llvm::ConstantInt::get(RHSTy, RHSMax);
5016 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5020 const Twine &Name) {
5021 llvm::IntegerType *Ty;
5022 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5027 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5028 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5030 return Builder.CreateURem(
5031 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5034Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5036 if (Ops.isFixedPointOp())
5037 return EmitFixedPointBinOp(Ops);
5041 Value *RHS = Ops.RHS;
5042 if (Ops.LHS->getType() != RHS->
getType())
5043 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5045 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5046 Ops.Ty->hasSignedIntegerRepresentation() &&
5049 bool SanitizeUnsignedBase =
5050 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5051 Ops.Ty->hasUnsignedIntegerRepresentation();
5052 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5053 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5056 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5057 else if ((SanitizeBase || SanitizeExponent) &&
5059 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5060 if (SanitizeSignedBase)
5061 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5062 if (SanitizeUnsignedBase)
5063 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5064 if (SanitizeExponent)
5065 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5067 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5068 SanitizerHandler::ShiftOutOfBounds);
5069 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5070 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5071 llvm::Value *WidthMinusOne =
5072 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5073 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5075 if (SanitizeExponent) {
5077 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5084 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5087 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5088 llvm::Value *PromotedWidthMinusOne =
5089 (RHS == Ops.RHS) ? WidthMinusOne
5090 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5092 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5093 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5102 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5103 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5105 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5106 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5108 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5109 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5110 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5111 Checks.push_back(std::make_pair(
5112 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5113 : SanitizerKind::SO_UnsignedShiftBase));
5116 assert(!Checks.empty());
5117 EmitBinOpCheck(Checks, Ops);
5120 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5123Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5125 if (Ops.isFixedPointOp())
5126 return EmitFixedPointBinOp(Ops);
5130 Value *RHS = Ops.RHS;
5131 if (Ops.LHS->getType() != RHS->
getType())
5132 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5136 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5137 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5139 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5140 SanitizerHandler::ShiftOutOfBounds);
5141 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5142 llvm::Value *
Valid = Builder.CreateICmpULE(
5143 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5144 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5147 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5148 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5149 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5157 default: llvm_unreachable(
"unexpected element type");
5158 case BuiltinType::Char_U:
5159 case BuiltinType::UChar:
5160 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5161 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5162 case BuiltinType::Char_S:
5163 case BuiltinType::SChar:
5164 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5165 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5166 case BuiltinType::UShort:
5167 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5168 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5169 case BuiltinType::Short:
5170 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5171 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5172 case BuiltinType::UInt:
5173 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5174 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5175 case BuiltinType::Int:
5176 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5177 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5178 case BuiltinType::ULong:
5179 case BuiltinType::ULongLong:
5180 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5181 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5182 case BuiltinType::Long:
5183 case BuiltinType::LongLong:
5184 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5185 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5186 case BuiltinType::Float:
5187 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5188 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5189 case BuiltinType::Double:
5190 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5191 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5192 case BuiltinType::UInt128:
5193 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5194 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5195 case BuiltinType::Int128:
5196 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5197 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5201Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5202 llvm::CmpInst::Predicate UICmpOpc,
5203 llvm::CmpInst::Predicate SICmpOpc,
5204 llvm::CmpInst::Predicate FCmpOpc,
5206 TestAndClearIgnoreResultAssign();
5210 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5216 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5218 BinOpInfo BOInfo = EmitBinOps(E);
5219 Value *LHS = BOInfo.LHS;
5220 Value *RHS = BOInfo.RHS;
5226 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5228 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5231 Value *FirstVecArg = LHS,
5232 *SecondVecArg = RHS;
5234 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5238 default: llvm_unreachable(
"is not a comparison operation");
5250 std::swap(FirstVecArg, SecondVecArg);
5257 if (ElementKind == BuiltinType::Float) {
5259 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5260 std::swap(FirstVecArg, SecondVecArg);
5268 if (ElementKind == BuiltinType::Float) {
5270 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5275 std::swap(FirstVecArg, SecondVecArg);
5280 Value *CR6Param = Builder.getInt32(CR6);
5282 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5290 if (ResultTy->getBitWidth() > 1 &&
5292 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5297 if (BOInfo.isFixedPointOp()) {
5298 Result = EmitFixedPointBinOp(BOInfo);
5299 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5300 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5302 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5304 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5306 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5321 LHS = Builder.CreateStripInvariantGroup(LHS);
5323 RHS = Builder.CreateStripInvariantGroup(RHS);
5326 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5332 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5338 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5340 CETy = CTy->getElementType();
5342 LHS.first = Visit(E->
getLHS());
5343 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5346 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5349 CTy->getElementType()) &&
5350 "The element types must always match.");
5353 RHS.first = Visit(E->
getRHS());
5354 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5356 "The element types must always match.");
5359 Value *ResultR, *ResultI;
5363 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5364 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5368 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5369 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5373 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5376 "Complex comparison other than == or != ?");
5377 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5389 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5390 CastKind Kind = ICE->getCastKind();
5391 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5392 *SrcType = ICE->getSubExpr()->getType();
5405 bool Ignore = TestAndClearIgnoreResultAssign();
5439 RHS = Visit(E->
getRHS());
5455 RHS = Visit(E->
getRHS());
5495 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5498Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5509 if (LHS->
getType()->isFPOrFPVectorTy()) {
5510 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5512 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5513 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5515 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5516 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5518 Value *
And = Builder.CreateAnd(LHS, RHS);
5519 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5523 llvm::Type *ResTy = ConvertType(E->
getType());
5542 if (InstrumentRegions &&
5546 llvm::BasicBlock *RHSSkip =
5549 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5566 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5577 return llvm::Constant::getNullValue(ResTy);
5588 llvm::BasicBlock *LHSFalseBlock =
5591 CodeGenFunction::ConditionalEvaluation eval(CGF);
5606 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5608 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5610 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5619 RHSBlock = Builder.GetInsertBlock();
5624 llvm::BasicBlock *ContIncoming = RHSBlock;
5625 if (InstrumentRegions &&
5629 llvm::BasicBlock *RHSBlockSkip =
5631 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5635 PN->addIncoming(RHSCond, RHSBlockCnt);
5640 ContIncoming = RHSBlockSkip;
5651 PN->addIncoming(RHSCond, ContIncoming);
5660 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5664 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5667Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5678 if (LHS->
getType()->isFPOrFPVectorTy()) {
5679 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5681 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5682 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5684 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5685 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5687 Value *
Or = Builder.CreateOr(LHS, RHS);
5688 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5692 llvm::Type *ResTy = ConvertType(E->
getType());
5711 if (InstrumentRegions &&
5715 llvm::BasicBlock *RHSSkip =
5718 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5735 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5746 return llvm::ConstantInt::get(ResTy, 1);
5756 llvm::BasicBlock *LHSTrueBlock =
5759 CodeGenFunction::ConditionalEvaluation eval(CGF);
5775 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5777 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5779 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5791 RHSBlock = Builder.GetInsertBlock();
5796 llvm::BasicBlock *ContIncoming = RHSBlock;
5797 if (InstrumentRegions &&
5801 llvm::BasicBlock *RHSTrueBlock =
5803 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5807 PN->addIncoming(RHSCond, RHSBlockCnt);
5812 ContIncoming = RHSTrueBlock;
5819 PN->addIncoming(RHSCond, ContIncoming);
5826 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5829Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5832 return Visit(E->
getRHS());
5857Value *ScalarExprEmitter::
5858VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5859 TestAndClearIgnoreResultAssign();
5862 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5864 Expr *condExpr = E->
getCond();
5872 Expr *live = lhsExpr, *dead = rhsExpr;
5873 if (!CondExprBool) std::swap(live, dead);
5900 llvm::Value *LHS = Visit(lhsExpr);
5901 llvm::Value *RHS = Visit(rhsExpr);
5903 llvm::Type *condType = ConvertType(condExpr->
getType());
5906 unsigned numElem = vecTy->getNumElements();
5907 llvm::Type *elemType = vecTy->getElementType();
5909 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5910 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5911 llvm::Value *tmp = Builder.CreateSExt(
5912 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5913 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5916 llvm::Value *RHSTmp = RHS;
5917 llvm::Value *LHSTmp = LHS;
5918 bool wasCast =
false;
5920 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5921 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5922 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5926 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5927 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5928 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5930 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5940 llvm::Value *LHS = Visit(lhsExpr);
5941 llvm::Value *RHS = Visit(rhsExpr);
5943 llvm::Type *CondType = ConvertType(condExpr->
getType());
5946 if (VecTy->getElementType()->isIntegerTy(1))
5947 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5950 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5952 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5954 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5955 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5965 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5969 llvm::Value *LHS = Visit(lhsExpr);
5970 llvm::Value *RHS = Visit(rhsExpr);
5973 assert(!RHS &&
"LHS and RHS types must match");
5976 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5987 CodeGenFunction::ConditionalEvaluation eval(CGF);
6001 Value *LHS = Visit(lhsExpr);
6004 LHSBlock = Builder.GetInsertBlock();
6005 Builder.CreateBr(ContBlock);
6017 Value *RHS = Visit(rhsExpr);
6020 RHSBlock = Builder.GetInsertBlock();
6030 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6031 PN->addIncoming(LHS, LHSBlock);
6032 PN->addIncoming(RHS, RHSBlock);
6037Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6041Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6043 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6048Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6054 Value *Src,
unsigned NumElementsDst) {
6055 static constexpr int Mask[] = {0, 1, 2, -1};
6056 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6076 const llvm::DataLayout &DL,
6077 Value *Src, llvm::Type *DstTy,
6078 StringRef Name =
"") {
6082 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6083 return Builder.CreateBitCast(Src, DstTy, Name);
6086 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6087 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6090 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6092 if (!DstTy->isIntegerTy())
6093 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6095 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6099 if (!SrcTy->isIntegerTy())
6100 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6102 return Builder.CreateIntToPtr(Src, DstTy, Name);
6105Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6107 llvm::Type *DstTy = ConvertType(E->
getType());
6109 llvm::Type *SrcTy = Src->
getType();
6110 unsigned NumElementsSrc =
6114 unsigned NumElementsDst =
6125 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6130 Src->setName(
"astype");
6137 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6138 auto *Vec4Ty = llvm::FixedVectorType::get(
6144 Src->setName(
"astype");
6149 Src, DstTy,
"astype");
6152Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6164 "Invalid scalar expression to emit");
6166 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6167 .Visit(
const_cast<Expr *
>(E));
6176 "Invalid scalar expression to emit");
6177 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6187 "Invalid complex -> scalar conversion");
6188 return ScalarExprEmitter(*
this)
6189 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6196 if (!PromotionType.
isNull())
6197 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6199 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6205 bool isInc,
bool isPre) {
6206 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6216 llvm::Type *BaseTy =
6232 ScalarExprEmitter Scalar(*
this);
6235#define COMPOUND_OP(Op) \
6236 case BO_##Op##Assign: \
6237 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6274 llvm_unreachable(
"Not valid compound assignment operators");
6277 llvm_unreachable(
"Unhandled compound assignment operator");
6292 llvm::LLVMContext &VMContext,
6298 llvm::Value *TotalOffset =
nullptr;
6304 Value *BasePtr_int =
6305 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6307 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6308 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6309 return {TotalOffset, Builder.getFalse()};
6313 assert(GEP->getPointerOperand() == BasePtr &&
6314 "BasePtr must be the base of the GEP.");
6315 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6317 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6320 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6321 auto *SAddIntrinsic =
6322 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6323 auto *SMulIntrinsic =
6324 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6327 llvm::Value *OffsetOverflows = Builder.getFalse();
6331 llvm::Value *RHS) -> llvm::Value * {
6332 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6335 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6336 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6338 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6341 OffsetOverflows = Builder.getTrue();
6342 return llvm::ConstantInt::get(VMContext, N);
6347 auto *ResultAndOverflow = Builder.CreateCall(
6348 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6349 OffsetOverflows = Builder.CreateOr(
6350 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6351 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6355 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6356 GTI != GTE; ++GTI) {
6357 llvm::Value *LocalOffset;
6358 auto *Index = GTI.getOperand();
6360 if (
auto *STy = GTI.getStructTypeOrNull()) {
6364 LocalOffset = llvm::ConstantInt::get(
6365 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6370 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6371 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6372 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6377 if (!TotalOffset || TotalOffset ==
Zero)
6378 TotalOffset = LocalOffset;
6380 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6383 return {TotalOffset, OffsetOverflows};
6388 ArrayRef<Value *> IdxList,
6389 bool SignedIndices,
bool IsSubtraction,
6390 SourceLocation Loc,
const Twine &Name) {
6391 llvm::Type *PtrTy = Ptr->
getType();
6393 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6394 if (!SignedIndices && !IsSubtraction)
6395 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6397 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6400 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6404 bool PerformNullCheck = !NullPointerIsDefined(
6405 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6408 bool PerformOverflowCheck =
6411 if (!(PerformNullCheck || PerformOverflowCheck))
6414 const auto &DL = CGM.getDataLayout();
6416 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6417 auto CheckHandler = SanitizerHandler::PointerOverflow;
6418 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6419 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6421 GEPOffsetAndOverflow EvaluatedGEP =
6426 "If the offset got constant-folded, we don't expect that there was an "
6429 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6437 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6438 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6440 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6444 if (PerformNullCheck) {
6452 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6453 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6454 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6455 Checks.emplace_back(
Valid, CheckOrdinal);
6458 if (PerformOverflowCheck) {
6463 llvm::Value *ValidGEP;
6464 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6465 if (SignedIndices) {
6471 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6472 auto *PosOrZeroOffset =
6474 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6476 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6477 }
else if (!IsSubtraction) {
6482 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6488 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6490 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6491 Checks.emplace_back(ValidGEP, CheckOrdinal);
6494 assert(!Checks.empty() &&
"Should have produced some checks.");
6496 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6498 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6499 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6505 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6506 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6507 const Twine &Name) {
6508 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6509 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6510 if (!SignedIndices && !IsSubtraction)
6511 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6513 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6517 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6518 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6519 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.
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())))
@ 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.