diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 4766 |
1 files changed, 4766 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp new file mode 100644 index 000000000000..55a413a2a717 --- /dev/null +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -0,0 +1,4766 @@ +//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This contains code to emit Expr nodes with scalar LLVM types as LLVM code. +// +//===----------------------------------------------------------------------===// + +#include "CGCXXABI.h" +#include "CGCleanup.h" +#include "CGDebugInfo.h" +#include "CGObjCRuntime.h" +#include "CodeGenFunction.h" +#include "CodeGenModule.h" +#include "ConstantEmitter.h" +#include "TargetInfo.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Expr.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/FixedPoint.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/Optional.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Module.h" +#include <cstdarg> + +using namespace clang; +using namespace CodeGen; +using llvm::Value; + +//===----------------------------------------------------------------------===// +// Scalar Expression Emitter +//===----------------------------------------------------------------------===// + +namespace { + +/// Determine whether the given binary operation may overflow. +/// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul, +/// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem}, +/// the returned overflow check is precise. The returned value is 'true' for +/// all other opcodes, to be conservative. +bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS, + BinaryOperator::Opcode Opcode, bool Signed, + llvm::APInt &Result) { + // Assume overflow is possible, unless we can prove otherwise. + bool Overflow = true; + const auto &LHSAP = LHS->getValue(); + const auto &RHSAP = RHS->getValue(); + if (Opcode == BO_Add) { + if (Signed) + Result = LHSAP.sadd_ov(RHSAP, Overflow); + else + Result = LHSAP.uadd_ov(RHSAP, Overflow); + } else if (Opcode == BO_Sub) { + if (Signed) + Result = LHSAP.ssub_ov(RHSAP, Overflow); + else + Result = LHSAP.usub_ov(RHSAP, Overflow); + } else if (Opcode == BO_Mul) { + if (Signed) + Result = LHSAP.smul_ov(RHSAP, Overflow); + else + Result = LHSAP.umul_ov(RHSAP, Overflow); + } else if (Opcode == BO_Div || Opcode == BO_Rem) { + if (Signed && !RHS->isZero()) + Result = LHSAP.sdiv_ov(RHSAP, Overflow); + else + return false; + } + return Overflow; +} + +struct BinOpInfo { + Value *LHS; + Value *RHS; + QualType Ty; // Computation Type. + BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform + FPOptions FPFeatures; + const Expr *E; // Entire expr, for error unsupported. May not be binop. + + /// Check if the binop can result in integer overflow. + bool mayHaveIntegerOverflow() const { + // Without constant input, we can't rule out overflow. + auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS); + auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS); + if (!LHSCI || !RHSCI) + return true; + + llvm::APInt Result; + return ::mayHaveIntegerOverflow( + LHSCI, RHSCI, Opcode, Ty->hasSignedIntegerRepresentation(), Result); + } + + /// Check if the binop computes a division or a remainder. + bool isDivremOp() const { + return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign || + Opcode == BO_RemAssign; + } + + /// Check if the binop can result in an integer division by zero. + bool mayHaveIntegerDivisionByZero() const { + if (isDivremOp()) + if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS)) + return CI->isZero(); + return true; + } + + /// Check if the binop can result in a float division by zero. + bool mayHaveFloatDivisionByZero() const { + if (isDivremOp()) + if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS)) + return CFP->isZero(); + return true; + } + + /// Check if either operand is a fixed point type or integer type, with at + /// least one being a fixed point type. In any case, this + /// operation did not follow usual arithmetic conversion and both operands may + /// not be the same. + bool isFixedPointBinOp() const { + // We cannot simply check the result type since comparison operations return + // an int. + if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) { + QualType LHSType = BinOp->getLHS()->getType(); + QualType RHSType = BinOp->getRHS()->getType(); + return LHSType->isFixedPointType() || RHSType->isFixedPointType(); + } + return false; + } +}; + +static bool MustVisitNullValue(const Expr *E) { + // If a null pointer expression's type is the C++0x nullptr_t, then + // it's not necessarily a simple constant and it must be evaluated + // for its potential side effects. + return E->getType()->isNullPtrType(); +} + +/// If \p E is a widened promoted integer, get its base (unpromoted) type. +static llvm::Optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx, + const Expr *E) { + const Expr *Base = E->IgnoreImpCasts(); + if (E == Base) + return llvm::None; + + QualType BaseTy = Base->getType(); + if (!BaseTy->isPromotableIntegerType() || + Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType())) + return llvm::None; + + return BaseTy; +} + +/// Check if \p E is a widened promoted integer. +static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) { + return getUnwidenedIntegerType(Ctx, E).hasValue(); +} + +/// Check if we can skip the overflow check for \p Op. +static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) { + assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) && + "Expected a unary or binary operator"); + + // If the binop has constant inputs and we can prove there is no overflow, + // we can elide the overflow check. + if (!Op.mayHaveIntegerOverflow()) + return true; + + // If a unary op has a widened operand, the op cannot overflow. + if (const auto *UO = dyn_cast<UnaryOperator>(Op.E)) + return !UO->canOverflow(); + + // We usually don't need overflow checks for binops with widened operands. + // Multiplication with promoted unsigned operands is a special case. + const auto *BO = cast<BinaryOperator>(Op.E); + auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS()); + if (!OptionalLHSTy) + return false; + + auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS()); + if (!OptionalRHSTy) + return false; + + QualType LHSTy = *OptionalLHSTy; + QualType RHSTy = *OptionalRHSTy; + + // This is the simple case: binops without unsigned multiplication, and with + // widened operands. No overflow check is needed here. + if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) || + !LHSTy->isUnsignedIntegerType() || !RHSTy->isUnsignedIntegerType()) + return true; + + // For unsigned multiplication the overflow check can be elided if either one + // of the unpromoted types are less than half the size of the promoted type. + unsigned PromotedSize = Ctx.getTypeSize(Op.E->getType()); + return (2 * Ctx.getTypeSize(LHSTy)) < PromotedSize || + (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize; +} + +/// Update the FastMathFlags of LLVM IR from the FPOptions in LangOptions. +static void updateFastMathFlags(llvm::FastMathFlags &FMF, + FPOptions FPFeatures) { + FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement()); +} + +/// Propagate fast-math flags from \p Op to the instruction in \p V. +static Value *propagateFMFlags(Value *V, const BinOpInfo &Op) { + if (auto *I = dyn_cast<llvm::Instruction>(V)) { + llvm::FastMathFlags FMF = I->getFastMathFlags(); + updateFastMathFlags(FMF, Op.FPFeatures); + I->setFastMathFlags(FMF); + } + return V; +} + +class ScalarExprEmitter + : public StmtVisitor<ScalarExprEmitter, Value*> { + CodeGenFunction &CGF; + CGBuilderTy &Builder; + bool IgnoreResultAssign; + llvm::LLVMContext &VMContext; +public: + + ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false) + : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira), + VMContext(cgf.getLLVMContext()) { + } + + //===--------------------------------------------------------------------===// + // Utilities + //===--------------------------------------------------------------------===// + + bool TestAndClearIgnoreResultAssign() { + bool I = IgnoreResultAssign; + IgnoreResultAssign = false; + return I; + } + + llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); } + LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); } + LValue EmitCheckedLValue(const Expr *E, CodeGenFunction::TypeCheckKind TCK) { + return CGF.EmitCheckedLValue(E, TCK); + } + + void EmitBinOpCheck(ArrayRef<std::pair<Value *, SanitizerMask>> Checks, + const BinOpInfo &Info); + + Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) { + return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal(); + } + + void EmitLValueAlignmentAssumption(const Expr *E, Value *V) { + const AlignValueAttr *AVAttr = nullptr; + if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { + const ValueDecl *VD = DRE->getDecl(); + + if (VD->getType()->isReferenceType()) { + if (const auto *TTy = + dyn_cast<TypedefType>(VD->getType().getNonReferenceType())) + AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>(); + } else { + // Assumptions for function parameters are emitted at the start of the + // function, so there is no need to repeat that here, + // unless the alignment-assumption sanitizer is enabled, + // then we prefer the assumption over alignment attribute + // on IR function param. + if (isa<ParmVarDecl>(VD) && !CGF.SanOpts.has(SanitizerKind::Alignment)) + return; + + AVAttr = VD->getAttr<AlignValueAttr>(); + } + } + + if (!AVAttr) + if (const auto *TTy = + dyn_cast<TypedefType>(E->getType())) + AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>(); + + if (!AVAttr) + return; + + Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment()); + llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue); + CGF.EmitAlignmentAssumption(V, E, AVAttr->getLocation(), AlignmentCI); + } + + /// EmitLoadOfLValue - Given an expression with complex type that represents a + /// value l-value, this method emits the address of the l-value, then loads + /// and returns the result. + Value *EmitLoadOfLValue(const Expr *E) { + Value *V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load), + E->getExprLoc()); + + EmitLValueAlignmentAssumption(E, V); + return V; + } + + /// EmitConversionToBool - Convert the specified expression value to a + /// boolean (i1) truth value. This is equivalent to "Val != 0". + Value *EmitConversionToBool(Value *Src, QualType DstTy); + + /// Emit a check that a conversion from a floating-point type does not + /// overflow. + void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType, + Value *Src, QualType SrcType, QualType DstType, + llvm::Type *DstTy, SourceLocation Loc); + + /// Known implicit conversion check kinds. + /// Keep in sync with the enum of the same name in ubsan_handlers.h + enum ImplicitConversionCheckKind : unsigned char { + ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7. + ICCK_UnsignedIntegerTruncation = 1, + ICCK_SignedIntegerTruncation = 2, + ICCK_IntegerSignChange = 3, + ICCK_SignedIntegerTruncationOrSignChange = 4, + }; + + /// Emit a check that an [implicit] truncation of an integer does not + /// discard any bits. It is not UB, so we use the value after truncation. + void EmitIntegerTruncationCheck(Value *Src, QualType SrcType, Value *Dst, + QualType DstType, SourceLocation Loc); + + /// Emit a check that an [implicit] conversion of an integer does not change + /// the sign of the value. It is not UB, so we use the value after conversion. + /// NOTE: Src and Dst may be the exact same value! (point to the same thing) + void EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst, + QualType DstType, SourceLocation Loc); + + /// Emit a conversion from the specified type to the specified destination + /// type, both of which are LLVM scalar types. + struct ScalarConversionOpts { + bool TreatBooleanAsSigned; + bool EmitImplicitIntegerTruncationChecks; + bool EmitImplicitIntegerSignChangeChecks; + + ScalarConversionOpts() + : TreatBooleanAsSigned(false), + EmitImplicitIntegerTruncationChecks(false), + EmitImplicitIntegerSignChangeChecks(false) {} + + ScalarConversionOpts(clang::SanitizerSet SanOpts) + : TreatBooleanAsSigned(false), + EmitImplicitIntegerTruncationChecks( + SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)), + EmitImplicitIntegerSignChangeChecks( + SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) {} + }; + Value * + EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy, + SourceLocation Loc, + ScalarConversionOpts Opts = ScalarConversionOpts()); + + /// Convert between either a fixed point and other fixed point or fixed point + /// and an integer. + Value *EmitFixedPointConversion(Value *Src, QualType SrcTy, QualType DstTy, + SourceLocation Loc); + Value *EmitFixedPointConversion(Value *Src, FixedPointSemantics &SrcFixedSema, + FixedPointSemantics &DstFixedSema, + SourceLocation Loc, + bool DstIsInteger = false); + + /// Emit a conversion from the specified complex type to the specified + /// destination type, where the destination type is an LLVM scalar type. + Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src, + QualType SrcTy, QualType DstTy, + SourceLocation Loc); + + /// EmitNullValue - Emit a value that corresponds to null for the given type. + Value *EmitNullValue(QualType Ty); + + /// EmitFloatToBoolConversion - Perform an FP to boolean conversion. + Value *EmitFloatToBoolConversion(Value *V) { + // Compare against 0.0 for fp scalars. + llvm::Value *Zero = llvm::Constant::getNullValue(V->getType()); + return Builder.CreateFCmpUNE(V, Zero, "tobool"); + } + + /// EmitPointerToBoolConversion - Perform a pointer to boolean conversion. + Value *EmitPointerToBoolConversion(Value *V, QualType QT) { + Value *Zero = CGF.CGM.getNullPointer(cast<llvm::PointerType>(V->getType()), QT); + + return Builder.CreateICmpNE(V, Zero, "tobool"); + } + + Value *EmitIntToBoolConversion(Value *V) { + // Because of the type rules of C, we often end up computing a + // logical value, then zero extending it to int, then wanting it + // as a logical value again. Optimize this common case. + if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) { + if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) { + Value *Result = ZI->getOperand(0); + // If there aren't any more uses, zap the instruction to save space. + // Note that there can be more uses, for example if this + // is the result of an assignment. + if (ZI->use_empty()) + ZI->eraseFromParent(); + return Result; + } + } + + return Builder.CreateIsNotNull(V, "tobool"); + } + + //===--------------------------------------------------------------------===// + // Visitor Methods + //===--------------------------------------------------------------------===// + + Value *Visit(Expr *E) { + ApplyDebugLocation DL(CGF, E); + return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E); + } + + Value *VisitStmt(Stmt *S) { + S->dump(CGF.getContext().getSourceManager()); + llvm_unreachable("Stmt can't have complex result type!"); + } + Value *VisitExpr(Expr *S); + + Value *VisitConstantExpr(ConstantExpr *E) { + return Visit(E->getSubExpr()); + } + Value *VisitParenExpr(ParenExpr *PE) { + return Visit(PE->getSubExpr()); + } + Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) { + return Visit(E->getReplacement()); + } + Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) { + return Visit(GE->getResultExpr()); + } + Value *VisitCoawaitExpr(CoawaitExpr *S) { + return CGF.EmitCoawaitExpr(*S).getScalarVal(); + } + Value *VisitCoyieldExpr(CoyieldExpr *S) { + return CGF.EmitCoyieldExpr(*S).getScalarVal(); + } + Value *VisitUnaryCoawait(const UnaryOperator *E) { + return Visit(E->getSubExpr()); + } + + // Leaves. + Value *VisitIntegerLiteral(const IntegerLiteral *E) { + return Builder.getInt(E->getValue()); + } + Value *VisitFixedPointLiteral(const FixedPointLiteral *E) { + return Builder.getInt(E->getValue()); + } + Value *VisitFloatingLiteral(const FloatingLiteral *E) { + return llvm::ConstantFP::get(VMContext, E->getValue()); + } + Value *VisitCharacterLiteral(const CharacterLiteral *E) { + return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue()); + } + Value *VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) { + return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue()); + } + Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { + return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue()); + } + Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) { + return EmitNullValue(E->getType()); + } + Value *VisitGNUNullExpr(const GNUNullExpr *E) { + return EmitNullValue(E->getType()); + } + Value *VisitOffsetOfExpr(OffsetOfExpr *E); + Value *VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E); + Value *VisitAddrLabelExpr(const AddrLabelExpr *E) { + llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel()); + return Builder.CreateBitCast(V, ConvertType(E->getType())); + } + + Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) { + return llvm::ConstantInt::get(ConvertType(E->getType()),E->getPackLength()); + } + + Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) { + return CGF.EmitPseudoObjectRValue(E).getScalarVal(); + } + + Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) { + if (E->isGLValue()) + return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E), + E->getExprLoc()); + + // Otherwise, assume the mapping is the scalar directly. + return CGF.getOrCreateOpaqueRValueMapping(E).getScalarVal(); + } + + // l-values. + Value *VisitDeclRefExpr(DeclRefExpr *E) { + if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) + return CGF.emitScalarConstant(Constant, E); + return EmitLoadOfLValue(E); + } + + Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) { + return CGF.EmitObjCSelectorExpr(E); + } + Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) { + return CGF.EmitObjCProtocolExpr(E); + } + Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { + return EmitLoadOfLValue(E); + } + Value *VisitObjCMessageExpr(ObjCMessageExpr *E) { + if (E->getMethodDecl() && + E->getMethodDecl()->getReturnType()->isReferenceType()) + return EmitLoadOfLValue(E); + return CGF.EmitObjCMessageExpr(E).getScalarVal(); + } + + Value *VisitObjCIsaExpr(ObjCIsaExpr *E) { + LValue LV = CGF.EmitObjCIsaExpr(E); + Value *V = CGF.EmitLoadOfLValue(LV, E->getExprLoc()).getScalarVal(); + return V; + } + + Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) { + VersionTuple Version = E->getVersion(); + + // If we're checking for a platform older than our minimum deployment + // target, we can fold the check away. + if (Version <= CGF.CGM.getTarget().getPlatformMinVersion()) + return llvm::ConstantInt::get(Builder.getInt1Ty(), 1); + + Optional<unsigned> Min = Version.getMinor(), SMin = Version.getSubminor(); + llvm::Value *Args[] = { + llvm::ConstantInt::get(CGF.CGM.Int32Ty, Version.getMajor()), + llvm::ConstantInt::get(CGF.CGM.Int32Ty, Min ? *Min : 0), + llvm::ConstantInt::get(CGF.CGM.Int32Ty, SMin ? *SMin : 0), + }; + + return CGF.EmitBuiltinAvailable(Args); + } + + Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E); + Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E); + Value *VisitConvertVectorExpr(ConvertVectorExpr *E); + Value *VisitMemberExpr(MemberExpr *E); + Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); } + Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { + return EmitLoadOfLValue(E); + } + + Value *VisitInitListExpr(InitListExpr *E); + + Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) { + assert(CGF.getArrayInitIndex() && + "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?"); + return CGF.getArrayInitIndex(); + } + + Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { + return EmitNullValue(E->getType()); + } + Value *VisitExplicitCastExpr(ExplicitCastExpr *E) { + CGF.CGM.EmitExplicitCastExprType(E, &CGF); + return VisitCastExpr(E); + } + Value *VisitCastExpr(CastExpr *E); + + Value *VisitCallExpr(const CallExpr *E) { + if (E->getCallReturnType(CGF.getContext())->isReferenceType()) + return EmitLoadOfLValue(E); + + Value *V = CGF.EmitCallExpr(E).getScalarVal(); + + EmitLValueAlignmentAssumption(E, V); + return V; + } + + Value *VisitStmtExpr(const StmtExpr *E); + + // Unary Operators. + Value *VisitUnaryPostDec(const UnaryOperator *E) { + LValue LV = EmitLValue(E->getSubExpr()); + return EmitScalarPrePostIncDec(E, LV, false, false); + } + Value *VisitUnaryPostInc(const UnaryOperator *E) { + LValue LV = EmitLValue(E->getSubExpr()); + return EmitScalarPrePostIncDec(E, LV, true, false); + } + Value *VisitUnaryPreDec(const UnaryOperator *E) { + LValue LV = EmitLValue(E->getSubExpr()); + return EmitScalarPrePostIncDec(E, LV, false, true); + } + Value *VisitUnaryPreInc(const UnaryOperator *E) { + LValue LV = EmitLValue(E->getSubExpr()); + return EmitScalarPrePostIncDec(E, LV, true, true); + } + + llvm::Value *EmitIncDecConsiderOverflowBehavior(const UnaryOperator *E, + llvm::Value *InVal, + bool IsInc); + + llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, + bool isInc, bool isPre); + + + Value *VisitUnaryAddrOf(const UnaryOperator *E) { + if (isa<MemberPointerType>(E->getType())) // never sugared + return CGF.CGM.getMemberPointerConstant(E); + + return EmitLValue(E->getSubExpr()).getPointer(); + } + Value *VisitUnaryDeref(const UnaryOperator *E) { + if (E->getType()->isVoidType()) + return Visit(E->getSubExpr()); // the actual value should be unused + return EmitLoadOfLValue(E); + } + Value *VisitUnaryPlus(const UnaryOperator *E) { + // This differs from gcc, though, most likely due to a bug in gcc. + TestAndClearIgnoreResultAssign(); + return Visit(E->getSubExpr()); + } + Value *VisitUnaryMinus (const UnaryOperator *E); + Value *VisitUnaryNot (const UnaryOperator *E); + Value *VisitUnaryLNot (const UnaryOperator *E); + Value *VisitUnaryReal (const UnaryOperator *E); + Value *VisitUnaryImag (const UnaryOperator *E); + Value *VisitUnaryExtension(const UnaryOperator *E) { + return Visit(E->getSubExpr()); + } + + // C++ + Value *VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E) { + return EmitLoadOfLValue(E); + } + Value *VisitSourceLocExpr(SourceLocExpr *SLE) { + auto &Ctx = CGF.getContext(); + APValue Evaluated = + SLE->EvaluateInContext(Ctx, CGF.CurSourceLocExprScope.getDefaultExpr()); + return ConstantEmitter(CGF.CGM, &CGF) + .emitAbstract(SLE->getLocation(), Evaluated, SLE->getType()); + } + + Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { + CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE); + return Visit(DAE->getExpr()); + } + Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { + CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE); + return Visit(DIE->getExpr()); + } + Value *VisitCXXThisExpr(CXXThisExpr *TE) { + return CGF.LoadCXXThis(); + } + + Value *VisitExprWithCleanups(ExprWithCleanups *E); + Value *VisitCXXNewExpr(const CXXNewExpr *E) { + return CGF.EmitCXXNewExpr(E); + } + Value *VisitCXXDeleteExpr(const CXXDeleteExpr *E) { + CGF.EmitCXXDeleteExpr(E); + return nullptr; + } + + Value *VisitTypeTraitExpr(const TypeTraitExpr *E) { + return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue()); + } + + Value *VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) { + return Builder.getInt1(E->isSatisfied()); + } + + Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) { + return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue()); + } + + Value *VisitExpressionTraitExpr(const ExpressionTraitExpr *E) { + return llvm::ConstantInt::get(Builder.getInt1Ty(), E->getValue()); + } + + Value *VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E) { + // C++ [expr.pseudo]p1: + // The result shall only be used as the operand for the function call + // operator (), and the result of such a call has type void. The only + // effect is the evaluation of the postfix-expression before the dot or + // arrow. + CGF.EmitScalarExpr(E->getBase()); + return nullptr; + } + + Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) { + return EmitNullValue(E->getType()); + } + + Value *VisitCXXThrowExpr(const CXXThrowExpr *E) { + CGF.EmitCXXThrowExpr(E); + return nullptr; + } + + Value *VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) { + return Builder.getInt1(E->getValue()); + } + + // Binary Operators. + Value *EmitMul(const BinOpInfo &Ops) { + if (Ops.Ty->isSignedIntegerOrEnumerationType()) { + switch (CGF.getLangOpts().getSignedOverflowBehavior()) { + case LangOptions::SOB_Defined: + return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); + case LangOptions::SOB_Undefined: + if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) + return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul"); + LLVM_FALLTHROUGH; + case LangOptions::SOB_Trapping: + if (CanElideOverflowCheck(CGF.getContext(), Ops)) + return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul"); + return EmitOverflowCheckedBinOp(Ops); + } + } + + if (Ops.Ty->isUnsignedIntegerType() && + CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) && + !CanElideOverflowCheck(CGF.getContext(), Ops)) + return EmitOverflowCheckedBinOp(Ops); + + if (Ops.LHS->getType()->isFPOrFPVectorTy()) { + Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul"); + return propagateFMFlags(V, Ops); + } + return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); + } + /// Create a binary op that checks for overflow. + /// Currently only supports +, - and *. + Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops); + + // Check for undefined division and modulus behaviors. + void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops, + llvm::Value *Zero,bool isDiv); + // Common helper for getting how wide LHS of shift is. + static Value *GetWidthMinusOneValue(Value* LHS,Value* RHS); + Value *EmitDiv(const BinOpInfo &Ops); + Value *EmitRem(const BinOpInfo &Ops); + Value *EmitAdd(const BinOpInfo &Ops); + Value *EmitSub(const BinOpInfo &Ops); + Value *EmitShl(const BinOpInfo &Ops); + Value *EmitShr(const BinOpInfo &Ops); + Value *EmitAnd(const BinOpInfo &Ops) { + return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and"); + } + Value *EmitXor(const BinOpInfo &Ops) { + return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor"); + } + Value *EmitOr (const BinOpInfo &Ops) { + return Builder.CreateOr(Ops.LHS, Ops.RHS, "or"); + } + + // Helper functions for fixed point binary operations. + Value *EmitFixedPointBinOp(const BinOpInfo &Ops); + + BinOpInfo EmitBinOps(const BinaryOperator *E); + LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, + Value *(ScalarExprEmitter::*F)(const BinOpInfo &), + Value *&Result); + + Value *EmitCompoundAssign(const CompoundAssignOperator *E, + Value *(ScalarExprEmitter::*F)(const BinOpInfo &)); + + // Binary operators and binary compound assignment operators. +#define HANDLEBINOP(OP) \ + Value *VisitBin ## OP(const BinaryOperator *E) { \ + return Emit ## OP(EmitBinOps(E)); \ + } \ + Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \ + return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \ + } + HANDLEBINOP(Mul) + HANDLEBINOP(Div) + HANDLEBINOP(Rem) + HANDLEBINOP(Add) + HANDLEBINOP(Sub) + HANDLEBINOP(Shl) + HANDLEBINOP(Shr) + HANDLEBINOP(And) + HANDLEBINOP(Xor) + HANDLEBINOP(Or) +#undef HANDLEBINOP + + // Comparisons. + Value *EmitCompare(const BinaryOperator *E, llvm::CmpInst::Predicate UICmpOpc, + llvm::CmpInst::Predicate SICmpOpc, + llvm::CmpInst::Predicate FCmpOpc); +#define VISITCOMP(CODE, UI, SI, FP) \ + Value *VisitBin##CODE(const BinaryOperator *E) { \ + return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \ + llvm::FCmpInst::FP); } + VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT) + VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT) + VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE) + VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE) + VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ) + VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE) +#undef VISITCOMP + + Value *VisitBinAssign (const BinaryOperator *E); + + Value *VisitBinLAnd (const BinaryOperator *E); + Value *VisitBinLOr (const BinaryOperator *E); + Value *VisitBinComma (const BinaryOperator *E); + + Value *VisitBinPtrMemD(const Expr *E) { return EmitLoadOfLValue(E); } + Value *VisitBinPtrMemI(const Expr *E) { return EmitLoadOfLValue(E); } + + Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) { + return Visit(E->getSemanticForm()); + } + + // Other Operators. + Value *VisitBlockExpr(const BlockExpr *BE); + Value *VisitAbstractConditionalOperator(const AbstractConditionalOperator *); + Value *VisitChooseExpr(ChooseExpr *CE); + Value *VisitVAArgExpr(VAArgExpr *VE); + Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) { + return CGF.EmitObjCStringLiteral(E); + } + Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) { + return CGF.EmitObjCBoxedExpr(E); + } + Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) { + return CGF.EmitObjCArrayLiteral(E); + } + Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { + return CGF.EmitObjCDictionaryLiteral(E); + } + Value *VisitAsTypeExpr(AsTypeExpr *CE); + Value *VisitAtomicExpr(AtomicExpr *AE); +}; +} // end anonymous namespace. + +//===----------------------------------------------------------------------===// +// Utilities +//===----------------------------------------------------------------------===// + +/// EmitConversionToBool - Convert the specified expression value to a +/// boolean (i1) truth value. This is equivalent to "Val != 0". +Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) { + assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs"); + + if (SrcType->isRealFloatingType()) + return EmitFloatToBoolConversion(Src); + + if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType)) + return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, Src, MPT); + + assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) && + "Unknown scalar type to convert"); + + if (isa<llvm::IntegerType>(Src->getType())) + return EmitIntToBoolConversion(Src); + + assert(isa<llvm::PointerType>(Src->getType())); + return EmitPointerToBoolConversion(Src, SrcType); +} + +void ScalarExprEmitter::EmitFloatConversionCheck( + Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType, + QualType DstType, llvm::Type *DstTy, SourceLocation Loc) { + assert(SrcType->isFloatingType() && "not a conversion from floating point"); + if (!isa<llvm::IntegerType>(DstTy)) + return; + + CodeGenFunction::SanitizerScope SanScope(&CGF); + using llvm::APFloat; + using llvm::APSInt; + + llvm::Value *Check = nullptr; + const llvm::fltSemantics &SrcSema = + CGF.getContext().getFloatTypeSemantics(OrigSrcType); + + // Floating-point to integer. This has undefined behavior if the source is + // +-Inf, NaN, or doesn't fit into the destination type (after truncation + // to an integer). + unsigned Width = CGF.getContext().getIntWidth(DstType); + bool Unsigned = DstType->isUnsignedIntegerOrEnumerationType(); + + APSInt Min = APSInt::getMinValue(Width, Unsigned); + APFloat MinSrc(SrcSema, APFloat::uninitialized); + if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) & + APFloat::opOverflow) + // Don't need an overflow check for lower bound. Just check for + // -Inf/NaN. + MinSrc = APFloat::getInf(SrcSema, true); + else + // Find the largest value which is too small to represent (before + // truncation toward zero). + MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative); + + APSInt Max = APSInt::getMaxValue(Width, Unsigned); + APFloat MaxSrc(SrcSema, APFloat::uninitialized); + if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) & + APFloat::opOverflow) + // Don't need an overflow check for upper bound. Just check for + // +Inf/NaN. + MaxSrc = APFloat::getInf(SrcSema, false); + else + // Find the smallest value which is too large to represent (before + // truncation toward zero). + MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive); + + // If we're converting from __half, convert the range to float to match + // the type of src. + if (OrigSrcType->isHalfType()) { + const llvm::fltSemantics &Sema = + CGF.getContext().getFloatTypeSemantics(SrcType); + bool IsInexact; + MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact); + MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact); + } + + llvm::Value *GE = + Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc)); + llvm::Value *LE = + Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc)); + Check = Builder.CreateAnd(GE, LE); + + llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc), + CGF.EmitCheckTypeDescriptor(OrigSrcType), + CGF.EmitCheckTypeDescriptor(DstType)}; + CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow), + SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc); +} + +// Should be called within CodeGenFunction::SanitizerScope RAII scope. +// Returns 'i1 false' when the truncation Src -> Dst was lossy. +static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, + std::pair<llvm::Value *, SanitizerMask>> +EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, + QualType DstType, CGBuilderTy &Builder) { + llvm::Type *SrcTy = Src->getType(); + llvm::Type *DstTy = Dst->getType(); + (void)DstTy; // Only used in assert() + + // This should be truncation of integral types. + assert(Src != Dst); + assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits()); + assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) && + "non-integer llvm type"); + + bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); + bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); + + // If both (src and dst) types are unsigned, then it's an unsigned truncation. + // Else, it is a signed truncation. + ScalarExprEmitter::ImplicitConversionCheckKind Kind; + SanitizerMask Mask; + if (!SrcSigned && !DstSigned) { + Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation; + Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation; + } else { + Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation; + Mask = SanitizerKind::ImplicitSignedIntegerTruncation; + } + + llvm::Value *Check = nullptr; + // 1. Extend the truncated value back to the same width as the Src. + Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned, "anyext"); + // 2. Equality-compare with the original source value + Check = Builder.CreateICmpEQ(Check, Src, "truncheck"); + // If the comparison result is 'i1 false', then the truncation was lossy. + return std::make_pair(Kind, std::make_pair(Check, Mask)); +} + +void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType, + Value *Dst, QualType DstType, + SourceLocation Loc) { + if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)) + return; + + // We only care about int->int conversions here. + // We ignore conversions to/from pointer and/or bool. + if (!(SrcType->isIntegerType() && DstType->isIntegerType())) + return; + + unsigned SrcBits = Src->getType()->getScalarSizeInBits(); + unsigned DstBits = Dst->getType()->getScalarSizeInBits(); + // This must be truncation. Else we do not care. + if (SrcBits <= DstBits) + return; + + assert(!DstType->isBooleanType() && "we should not get here with booleans."); + + // If the integer sign change sanitizer is enabled, + // and we are truncating from larger unsigned type to smaller signed type, + // let that next sanitizer deal with it. + bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); + bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); + if (CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange) && + (!SrcSigned && DstSigned)) + return; + + CodeGenFunction::SanitizerScope SanScope(&CGF); + + std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, + std::pair<llvm::Value *, SanitizerMask>> + Check = + EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder); + // If the comparison result is 'i1 false', then the truncation was lossy. + + // Do we care about this type of truncation? + if (!CGF.SanOpts.has(Check.second.second)) + return; + + llvm::Constant *StaticArgs[] = { + CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType), + CGF.EmitCheckTypeDescriptor(DstType), + llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)}; + CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs, + {Src, Dst}); +} + +// Should be called within CodeGenFunction::SanitizerScope RAII scope. +// Returns 'i1 false' when the conversion Src -> Dst changed the sign. +static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, + std::pair<llvm::Value *, SanitizerMask>> +EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, + QualType DstType, CGBuilderTy &Builder) { + llvm::Type *SrcTy = Src->getType(); + llvm::Type *DstTy = Dst->getType(); + + assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) && + "non-integer llvm type"); + + bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); + bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); + (void)SrcSigned; // Only used in assert() + (void)DstSigned; // Only used in assert() + unsigned SrcBits = SrcTy->getScalarSizeInBits(); + unsigned DstBits = DstTy->getScalarSizeInBits(); + (void)SrcBits; // Only used in assert() + (void)DstBits; // Only used in assert() + + assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) && + "either the widths should be different, or the signednesses."); + + // NOTE: zero value is considered to be non-negative. + auto EmitIsNegativeTest = [&Builder](Value *V, QualType VType, + const char *Name) -> Value * { + // Is this value a signed type? + bool VSigned = VType->isSignedIntegerOrEnumerationType(); + llvm::Type *VTy = V->getType(); + if (!VSigned) { + // If the value is unsigned, then it is never negative. + // FIXME: can we encounter non-scalar VTy here? + return llvm::ConstantInt::getFalse(VTy->getContext()); + } + // Get the zero of the same type with which we will be comparing. + llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0); + // %V.isnegative = icmp slt %V, 0 + // I.e is %V *strictly* less than zero, does it have negative value? + return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero, + llvm::Twine(Name) + "." + V->getName() + + ".negativitycheck"); + }; + + // 1. Was the old Value negative? + llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType, "src"); + // 2. Is the new Value negative? + llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType, "dst"); + // 3. Now, was the 'negativity status' preserved during the conversion? + // NOTE: conversion from negative to zero is considered to change the sign. + // (We want to get 'false' when the conversion changed the sign) + // So we should just equality-compare the negativity statuses. + llvm::Value *Check = nullptr; + Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "signchangecheck"); + // If the comparison result is 'false', then the conversion changed the sign. + return std::make_pair( + ScalarExprEmitter::ICCK_IntegerSignChange, + std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange)); +} + +void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, + Value *Dst, QualType DstType, + SourceLocation Loc) { + if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) + return; + + llvm::Type *SrcTy = Src->getType(); + llvm::Type *DstTy = Dst->getType(); + + // We only care about int->int conversions here. + // We ignore conversions to/from pointer and/or bool. + if (!(SrcType->isIntegerType() && DstType->isIntegerType())) + return; + + bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); + bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); + unsigned SrcBits = SrcTy->getScalarSizeInBits(); + unsigned DstBits = DstTy->getScalarSizeInBits(); + + // Now, we do not need to emit the check in *all* of the cases. + // We can avoid emitting it in some obvious cases where it would have been + // dropped by the opt passes (instcombine) always anyways. + // If it's a cast between effectively the same type, no check. + // NOTE: this is *not* equivalent to checking the canonical types. + if (SrcSigned == DstSigned && SrcBits == DstBits) + return; + // At least one of the values needs to have signed type. + // If both are unsigned, then obviously, neither of them can be negative. + if (!SrcSigned && !DstSigned) + return; + // If the conversion is to *larger* *signed* type, then no check is needed. + // Because either sign-extension happens (so the sign will remain), + // or zero-extension will happen (the sign bit will be zero.) + if ((DstBits > SrcBits) && DstSigned) + return; + if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) && + (SrcBits > DstBits) && SrcSigned) { + // If the signed integer truncation sanitizer is enabled, + // and this is a truncation from signed type, then no check is needed. + // Because here sign change check is interchangeable with truncation check. + return; + } + // That's it. We can't rule out any more cases with the data we have. + + CodeGenFunction::SanitizerScope SanScope(&CGF); + + std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, + std::pair<llvm::Value *, SanitizerMask>> + Check; + + // Each of these checks needs to return 'false' when an issue was detected. + ImplicitConversionCheckKind CheckKind; + llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; + // So we can 'and' all the checks together, and still get 'false', + // if at least one of the checks detected an issue. + + Check = EmitIntegerSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder); + CheckKind = Check.first; + Checks.emplace_back(Check.second); + + if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) && + (SrcBits > DstBits) && !SrcSigned && DstSigned) { + // If the signed integer truncation sanitizer was enabled, + // and we are truncating from larger unsigned type to smaller signed type, + // let's handle the case we skipped in that check. + Check = + EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder); + CheckKind = ICCK_SignedIntegerTruncationOrSignChange; + Checks.emplace_back(Check.second); + // If the comparison result is 'i1 false', then the truncation was lossy. + } + + llvm::Constant *StaticArgs[] = { + CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType), + CGF.EmitCheckTypeDescriptor(DstType), + llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)}; + // EmitCheck() will 'and' all the checks together. + CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs, + {Src, Dst}); +} + +/// Emit a conversion from the specified type to the specified destination type, +/// both of which are LLVM scalar types. +Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, + QualType DstType, + SourceLocation Loc, + ScalarConversionOpts Opts) { + // All conversions involving fixed point types should be handled by the + // EmitFixedPoint family functions. This is done to prevent bloating up this + // function more, and although fixed point numbers are represented by + // integers, we do not want to follow any logic that assumes they should be + // treated as integers. + // TODO(leonardchan): When necessary, add another if statement checking for + // conversions to fixed point types from other types. + if (SrcType->isFixedPointType()) { + if (DstType->isBooleanType()) + // It is important that we check this before checking if the dest type is + // an integer because booleans are technically integer types. + // We do not need to check the padding bit on unsigned types if unsigned + // padding is enabled because overflow into this bit is undefined + // behavior. + return Builder.CreateIsNotNull(Src, "tobool"); + if (DstType->isFixedPointType() || DstType->isIntegerType()) + return EmitFixedPointConversion(Src, SrcType, DstType, Loc); + + llvm_unreachable( + "Unhandled scalar conversion from a fixed point type to another type."); + } else if (DstType->isFixedPointType()) { + if (SrcType->isIntegerType()) + // This also includes converting booleans and enums to fixed point types. + return EmitFixedPointConversion(Src, SrcType, DstType, Loc); + + llvm_unreachable( + "Unhandled scalar conversion to a fixed point type from another type."); + } + + QualType NoncanonicalSrcType = SrcType; + QualType NoncanonicalDstType = DstType; + + SrcType = CGF.getContext().getCanonicalType(SrcType); + DstType = CGF.getContext().getCanonicalType(DstType); + if (SrcType == DstType) return Src; + + if (DstType->isVoidType()) return nullptr; + + llvm::Value *OrigSrc = Src; + QualType OrigSrcType = SrcType; + llvm::Type *SrcTy = Src->getType(); + + // Handle conversions to bool first, they are special: comparisons against 0. + if (DstType->isBooleanType()) + return EmitConversionToBool(Src, SrcType); + + llvm::Type *DstTy = ConvertType(DstType); + + // Cast from half through float if half isn't a native type. + if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { + // Cast to FP using the intrinsic if the half type itself isn't supported. + if (DstTy->isFloatingPointTy()) { + if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) + return Builder.CreateCall( + CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, DstTy), + Src); + } else { + // Cast to other types through float, using either the intrinsic or FPExt, + // depending on whether the half type itself is supported + // (as opposed to operations on half, available with NativeHalfType). + if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) { + Src = Builder.CreateCall( + CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, + CGF.CGM.FloatTy), + Src); + } else { + Src = Builder.CreateFPExt(Src, CGF.CGM.FloatTy, "conv"); + } + SrcType = CGF.getContext().FloatTy; + SrcTy = CGF.FloatTy; + } + } + + // Ignore conversions like int -> uint. + if (SrcTy == DstTy) { + if (Opts.EmitImplicitIntegerSignChangeChecks) + EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src, + NoncanonicalDstType, Loc); + + return Src; + } + + // Handle pointer conversions next: pointers can only be converted to/from + // other pointers and integers. Check for pointer types in terms of LLVM, as + // some native types (like Obj-C id) may map to a pointer type. + if (auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) { + // The source value may be an integer, or a pointer. + if (isa<llvm::PointerType>(SrcTy)) + return Builder.CreateBitCast(Src, DstTy, "conv"); + + assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?"); + // First, convert to the correct width so that we control the kind of + // extension. + llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DstPT); + bool InputSigned = SrcType->isSignedIntegerOrEnumerationType(); + llvm::Value* IntResult = + Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv"); + // Then, cast to pointer. + return Builder.CreateIntToPtr(IntResult, DstTy, "conv"); + } + + if (isa<llvm::PointerType>(SrcTy)) { + // Must be an ptr to int cast. + assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?"); + return Builder.CreatePtrToInt(Src, DstTy, "conv"); + } + + // A scalar can be splatted to an extended vector of the same element type + if (DstType->isExtVectorType() && !SrcType->isVectorType()) { + // Sema should add casts to make sure that the source expression's type is + // the same as the vector's element type (sans qualifiers) + assert(DstType->castAs<ExtVectorType>()->getElementType().getTypePtr() == + SrcType.getTypePtr() && + "Splatted expr doesn't match with vector element type?"); + + // Splat the element across to all elements + unsigned NumElements = DstTy->getVectorNumElements(); + return Builder.CreateVectorSplat(NumElements, Src, "splat"); + } + + if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) { + // Allow bitcast from vector to integer/fp of the same size. + unsigned SrcSize = SrcTy->getPrimitiveSizeInBits(); + unsigned DstSize = DstTy->getPrimitiveSizeInBits(); + if (SrcSize == DstSize) + return Builder.CreateBitCast(Src, DstTy, "conv"); + + // Conversions between vectors of different sizes are not allowed except + // when vectors of half are involved. Operations on storage-only half + // vectors require promoting half vector operands to float vectors and + // truncating the result, which is either an int or float vector, to a + // short or half vector. + + // Source and destination are both expected to be vectors. + llvm::Type *SrcElementTy = SrcTy->getVectorElementType(); + llvm::Type *DstElementTy = DstTy->getVectorElementType(); + (void)DstElementTy; + + assert(((SrcElementTy->isIntegerTy() && + DstElementTy->isIntegerTy()) || + (SrcElementTy->isFloatingPointTy() && + DstElementTy->isFloatingPointTy())) && + "unexpected conversion between a floating-point vector and an " + "integer vector"); + + // Truncate an i32 vector to an i16 vector. + if (SrcElementTy->isIntegerTy()) + return Builder.CreateIntCast(Src, DstTy, false, "conv"); + + // Truncate a float vector to a half vector. + if (SrcSize > DstSize) + return Builder.CreateFPTrunc(Src, DstTy, "conv"); + + // Promote a half vector to a float vector. + return Builder.CreateFPExt(Src, DstTy, "conv"); + } + + // Finally, we have the arithmetic types: real int/float. + Value *Res = nullptr; + llvm::Type *ResTy = DstTy; + + // An overflowing conversion has undefined behavior if either the source type + // or the destination type is a floating-point type. However, we consider the + // range of representable values for all floating-point types to be + // [-inf,+inf], so no overflow can ever happen when the destination type is a + // floating-point type. + if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) && + OrigSrcType->isFloatingType()) + EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy, + Loc); + + // Cast to half through float if half isn't a native type. + if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { + // Make sure we cast in a single step if from another FP type. + if (SrcTy->isFloatingPointTy()) { + // Use the intrinsic if the half type itself isn't supported + // (as opposed to operations on half, available with NativeHalfType). + if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) + return Builder.CreateCall( + CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, SrcTy), Src); + // If the half type is supported, just use an fptrunc. + return Builder.CreateFPTrunc(Src, DstTy); + } + DstTy = CGF.FloatTy; + } + + if (isa<llvm::IntegerType>(SrcTy)) { + bool InputSigned = SrcType->isSignedIntegerOrEnumerationType(); + if (SrcType->isBooleanType() && Opts.TreatBooleanAsSigned) { + InputSigned = true; + } + if (isa<llvm::IntegerType>(DstTy)) + Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"); + else if (InputSigned) + Res = Builder.CreateSIToFP(Src, DstTy, "conv"); + else + Res = Builder.CreateUIToFP(Src, DstTy, "conv"); + } else if (isa<llvm::IntegerType>(DstTy)) { + assert(SrcTy->isFloatingPointTy() && "Unknown real conversion"); + if (DstType->isSignedIntegerOrEnumerationType()) + Res = Builder.CreateFPToSI(Src, DstTy, "conv"); + else + Res = Builder.CreateFPToUI(Src, DstTy, "conv"); + } else { + assert(SrcTy->isFloatingPointTy() && DstTy->isFloatingPointTy() && + "Unknown real conversion"); + if (DstTy->getTypeID() < SrcTy->getTypeID()) + Res = Builder.CreateFPTrunc(Src, DstTy, "conv"); + else + Res = Builder.CreateFPExt(Src, DstTy, "conv"); + } + + if (DstTy != ResTy) { + if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) { + assert(ResTy->isIntegerTy(16) && "Only half FP requires extra conversion"); + Res = Builder.CreateCall( + CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, CGF.CGM.FloatTy), + Res); + } else { + Res = Builder.CreateFPTrunc(Res, ResTy, "conv"); + } + } + + if (Opts.EmitImplicitIntegerTruncationChecks) + EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res, + NoncanonicalDstType, Loc); + + if (Opts.EmitImplicitIntegerSignChangeChecks) + EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res, + NoncanonicalDstType, Loc); + + return Res; +} + +Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy, + QualType DstTy, + SourceLocation Loc) { + FixedPointSemantics SrcFPSema = + CGF.getContext().getFixedPointSemantics(SrcTy); + FixedPointSemantics DstFPSema = + CGF.getContext().getFixedPointSemantics(DstTy); + return EmitFixedPointConversion(Src, SrcFPSema, DstFPSema, Loc, + DstTy->isIntegerType()); +} + +Value *ScalarExprEmitter::EmitFixedPointConversion( + Value *Src, FixedPointSemantics &SrcFPSema, FixedPointSemantics &DstFPSema, + SourceLocation Loc, bool DstIsInteger) { + using llvm::APInt; + using llvm::ConstantInt; + using llvm::Value; + + unsigned SrcWidth = SrcFPSema.getWidth(); + unsigned DstWidth = DstFPSema.getWidth(); + unsigned SrcScale = SrcFPSema.getScale(); + unsigned DstScale = DstFPSema.getScale(); + bool SrcIsSigned = SrcFPSema.isSigned(); + bool DstIsSigned = DstFPSema.isSigned(); + + llvm::Type *DstIntTy = Builder.getIntNTy(DstWidth); + + Value *Result = Src; + unsigned ResultWidth = SrcWidth; + + // Downscale. + if (DstScale < SrcScale) { + // When converting to integers, we round towards zero. For negative numbers, + // right shifting rounds towards negative infinity. In this case, we can + // just round up before shifting. + if (DstIsInteger && SrcIsSigned) { + Value *Zero = llvm::Constant::getNullValue(Result->getType()); + Value *IsNegative = Builder.CreateICmpSLT(Result, Zero); + Value *LowBits = ConstantInt::get( + CGF.getLLVMContext(), APInt::getLowBitsSet(ResultWidth, SrcScale)); + Value *Rounded = Builder.CreateAdd(Result, LowBits); + Result = Builder.CreateSelect(IsNegative, Rounded, Result); + } + + Result = SrcIsSigned + ? Builder.CreateAShr(Result, SrcScale - DstScale, "downscale") + : Builder.CreateLShr(Result, SrcScale - DstScale, "downscale"); + } + + if (!DstFPSema.isSaturated()) { + // Resize. + Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize"); + + // Upscale. + if (DstScale > SrcScale) + Result = Builder.CreateShl(Result, DstScale - SrcScale, "upscale"); + } else { + // Adjust the number of fractional bits. + if (DstScale > SrcScale) { + // Compare to DstWidth to prevent resizing twice. + ResultWidth = std::max(SrcWidth + DstScale - SrcScale, DstWidth); + llvm::Type *UpscaledTy = Builder.getIntNTy(ResultWidth); + Result = Builder.CreateIntCast(Result, UpscaledTy, SrcIsSigned, "resize"); + Result = Builder.CreateShl(Result, DstScale - SrcScale, "upscale"); + } + + // Handle saturation. + bool LessIntBits = DstFPSema.getIntegralBits() < SrcFPSema.getIntegralBits(); + if (LessIntBits) { + Value *Max = ConstantInt::get( + CGF.getLLVMContext(), + APFixedPoint::getMax(DstFPSema).getValue().extOrTrunc(ResultWidth)); + Value *TooHigh = SrcIsSigned ? Builder.CreateICmpSGT(Result, Max) + : Builder.CreateICmpUGT(Result, Max); + Result = Builder.CreateSelect(TooHigh, Max, Result, "satmax"); + } + // Cannot overflow min to dest type if src is unsigned since all fixed + // point types can cover the unsigned min of 0. + if (SrcIsSigned && (LessIntBits || !DstIsSigned)) { + Value *Min = ConstantInt::get( + CGF.getLLVMContext(), + APFixedPoint::getMin(DstFPSema).getValue().extOrTrunc(ResultWidth)); + Value *TooLow = Builder.CreateICmpSLT(Result, Min); + Result = Builder.CreateSelect(TooLow, Min, Result, "satmin"); + } + + // Resize the integer part to get the final destination size. + if (ResultWidth != DstWidth) + Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize"); + } + return Result; +} + +/// Emit a conversion from the specified complex type to the specified +/// destination type, where the destination type is an LLVM scalar type. +Value *ScalarExprEmitter::EmitComplexToScalarConversion( + CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy, + SourceLocation Loc) { + // Get the source element type. + SrcTy = SrcTy->castAs<ComplexType>()->getElementType(); + + // Handle conversions to bool first, they are special: comparisons against 0. + if (DstTy->isBooleanType()) { + // Complex != 0 -> (Real != 0) | (Imag != 0) + Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc); + Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc); + return Builder.CreateOr(Src.first, Src.second, "tobool"); + } + + // C99 6.3.1.7p2: "When a value of complex type is converted to a real type, + // the imaginary part of the complex value is discarded and the value of the + // real part is converted according to the conversion rules for the + // corresponding real type. + return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc); +} + +Value *ScalarExprEmitter::EmitNullValue(QualType Ty) { + return CGF.EmitFromMemory(CGF.CGM.EmitNullConstant(Ty), Ty); +} + +/// Emit a sanitization check for the given "binary" operation (which +/// might actually be a unary increment which has been lowered to a binary +/// operation). The check passes if all values in \p Checks (which are \c i1), +/// are \c true. +void ScalarExprEmitter::EmitBinOpCheck( + ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) { + assert(CGF.IsSanitizerScope); + SanitizerHandler Check; + SmallVector<llvm::Constant *, 4> StaticData; + SmallVector<llvm::Value *, 2> DynamicData; + + BinaryOperatorKind Opcode = Info.Opcode; + if (BinaryOperator::isCompoundAssignmentOp(Opcode)) + Opcode = BinaryOperator::getOpForCompoundAssignment(Opcode); + + StaticData.push_back(CGF.EmitCheckSourceLocation(Info.E->getExprLoc())); + const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E); + if (UO && UO->getOpcode() == UO_Minus) { + Check = SanitizerHandler::NegateOverflow; + StaticData.push_back(CGF.EmitCheckTypeDescriptor(UO->getType())); + DynamicData.push_back(Info.RHS); + } else { + if (BinaryOperator::isShiftOp(Opcode)) { + // Shift LHS negative or too large, or RHS out of bounds. + Check = SanitizerHandler::ShiftOutOfBounds; + const BinaryOperator *BO = cast<BinaryOperator>(Info.E); + StaticData.push_back( + CGF.EmitCheckTypeDescriptor(BO->getLHS()->getType())); + StaticData.push_back( + CGF.EmitCheckTypeDescriptor(BO->getRHS()->getType())); + } else if (Opcode == BO_Div || Opcode == BO_Rem) { + // Divide or modulo by zero, or signed overflow (eg INT_MAX / -1). + Check = SanitizerHandler::DivremOverflow; + StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty)); + } else { + // Arithmetic overflow (+, -, *). + switch (Opcode) { + case BO_Add: Check = SanitizerHandler::AddOverflow; break; + case BO_Sub: Check = SanitizerHandler::SubOverflow; break; + case BO_Mul: Check = SanitizerHandler::MulOverflow; break; + default: llvm_unreachable("unexpected opcode for bin op check"); + } + StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty)); + } + DynamicData.push_back(Info.LHS); + DynamicData.push_back(Info.RHS); + } + + CGF.EmitCheck(Checks, Check, StaticData, DynamicData); +} + +//===----------------------------------------------------------------------===// +// Visitor Methods +//===----------------------------------------------------------------------===// + +Value *ScalarExprEmitter::VisitExpr(Expr *E) { + CGF.ErrorUnsupported(E, "scalar expression"); + if (E->getType()->isVoidType()) + return nullptr; + return llvm::UndefValue::get(CGF.ConvertType(E->getType())); +} + +Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { + // Vector Mask Case + if (E->getNumSubExprs() == 2) { + Value *LHS = CGF.EmitScalarExpr(E->getExpr(0)); + Value *RHS = CGF.EmitScalarExpr(E->getExpr(1)); + Value *Mask; + + llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType()); + unsigned LHSElts = LTy->getNumElements(); + + Mask = RHS; + + llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType()); + + // Mask off the high bits of each shuffle index. + Value *MaskBits = + llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1); + Mask = Builder.CreateAnd(Mask, MaskBits, "mask"); + + // newv = undef + // mask = mask & maskbits + // for each elt + // n = extract mask i + // x = extract val n + // newv = insert newv, x, i + llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(), + MTy->getNumElements()); + Value* NewV = llvm::UndefValue::get(RTy); + for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) { + Value *IIndx = llvm::ConstantInt::get(CGF.SizeTy, i); + Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx"); + + Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt"); + NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins"); + } + return NewV; + } + + Value* V1 = CGF.EmitScalarExpr(E->getExpr(0)); + Value* V2 = CGF.EmitScalarExpr(E->getExpr(1)); + + SmallVector<llvm::Constant*, 32> indices; + for (unsigned i = 2; i < E->getNumSubExprs(); ++i) { + llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2); + // Check for -1 and output it as undef in the IR. + if (Idx.isSigned() && Idx.isAllOnesValue()) + indices.push_back(llvm::UndefValue::get(CGF.Int32Ty)); + else + indices.push_back(Builder.getInt32(Idx.getZExtValue())); + } + + Value *SV = llvm::ConstantVector::get(indices); + return Builder.CreateShuffleVector(V1, V2, SV, "shuffle"); +} + +Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) { + QualType SrcType = E->getSrcExpr()->getType(), + DstType = E->getType(); + + Value *Src = CGF.EmitScalarExpr(E->getSrcExpr()); + + SrcType = CGF.getContext().getCanonicalType(SrcType); + DstType = CGF.getContext().getCanonicalType(DstType); + if (SrcType == DstType) return Src; + + assert(SrcType->isVectorType() && + "ConvertVector source type must be a vector"); + assert(DstType->isVectorType() && + "ConvertVector destination type must be a vector"); + + llvm::Type *SrcTy = Src->getType(); + llvm::Type *DstTy = ConvertType(DstType); + + // Ignore conversions like int -> uint. + if (SrcTy == DstTy) + return Src; + + QualType SrcEltType = SrcType->castAs<VectorType>()->getElementType(), + DstEltType = DstType->castAs<VectorType>()->getElementType(); + + assert(SrcTy->isVectorTy() && + "ConvertVector source IR type must be a vector"); + assert(DstTy->isVectorTy() && + "ConvertVector destination IR type must be a vector"); + + llvm::Type *SrcEltTy = SrcTy->getVectorElementType(), + *DstEltTy = DstTy->getVectorElementType(); + + if (DstEltType->isBooleanType()) { + assert((SrcEltTy->isFloatingPointTy() || + isa<llvm::IntegerType>(SrcEltTy)) && "Unknown boolean conversion"); + + llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy); + if (SrcEltTy->isFloatingPointTy()) { + return Builder.CreateFCmpUNE(Src, Zero, "tobool"); + } else { + return Builder.CreateICmpNE(Src, Zero, "tobool"); + } + } + + // We have the arithmetic types: real int/float. + Value *Res = nullptr; + + if (isa<llvm::IntegerType>(SrcEltTy)) { + bool InputSigned = SrcEltType->isSignedIntegerOrEnumerationType(); + if (isa<llvm::IntegerType>(DstEltTy)) + Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"); + else if (InputSigned) + Res = Builder.CreateSIToFP(Src, DstTy, "conv"); + else + Res = Builder.CreateUIToFP(Src, DstTy, "conv"); + } else if (isa<llvm::IntegerType>(DstEltTy)) { + assert(SrcEltTy->isFloatingPointTy() && "Unknown real conversion"); + if (DstEltType->isSignedIntegerOrEnumerationType()) + Res = Builder.CreateFPToSI(Src, DstTy, "conv"); + else + Res = Builder.CreateFPToUI(Src, DstTy, "conv"); + } else { + assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() && + "Unknown real conversion"); + if (DstEltTy->getTypeID() < SrcEltTy->getTypeID()) + Res = Builder.CreateFPTrunc(Src, DstTy, "conv"); + else + Res = Builder.CreateFPExt(Src, DstTy, "conv"); + } + + return Res; +} + +Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) { + if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) { + CGF.EmitIgnoredExpr(E->getBase()); + return CGF.emitScalarConstant(Constant, E); + } else { + Expr::EvalResult Result; + if (E->EvaluateAsInt(Result, CGF.getContext(), Expr::SE_AllowSideEffects)) { + llvm::APSInt Value = Result.Val.getInt(); + CGF.EmitIgnoredExpr(E->getBase()); + return Builder.getInt(Value); + } + } + + return EmitLoadOfLValue(E); +} + +Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { + TestAndClearIgnoreResultAssign(); + + // Emit subscript expressions in rvalue context's. For most cases, this just + // loads the lvalue formed by the subscript expr. However, we have to be + // careful, because the base of a vector subscript is occasionally an rvalue, + // so we can't get it as an lvalue. + if (!E->getBase()->getType()->isVectorType()) + return EmitLoadOfLValue(E); + + // Handle the vector case. The base must be a vector, the index must be an + // integer value. + Value *Base = Visit(E->getBase()); + Value *Idx = Visit(E->getIdx()); + QualType IdxTy = E->getIdx()->getType(); + + if (CGF.SanOpts.has(SanitizerKind::ArrayBounds)) + CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true); + + return Builder.CreateExtractElement(Base, Idx, "vecext"); +} + +static llvm::Constant *getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, + unsigned Off, llvm::Type *I32Ty) { + int MV = SVI->getMaskValue(Idx); + if (MV == -1) + return llvm::UndefValue::get(I32Ty); + return llvm::ConstantInt::get(I32Ty, Off+MV); +} + +static llvm::Constant *getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty) { + if (C->getBitWidth() != 32) { + assert(llvm::ConstantInt::isValueValidForType(I32Ty, + C->getZExtValue()) && + "Index operand too large for shufflevector mask!"); + return llvm::ConstantInt::get(I32Ty, C->getZExtValue()); + } + return C; +} + +Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { + bool Ignore = TestAndClearIgnoreResultAssign(); + (void)Ignore; + assert (Ignore == false && "init list ignored"); + unsigned NumInitElements = E->getNumInits(); + + if (E->hadArrayRangeDesignator()) + CGF.ErrorUnsupported(E, "GNU array range designator extension"); + + llvm::VectorType *VType = + dyn_cast<llvm::VectorType>(ConvertType(E->getType())); + + if (!VType) { + if (NumInitElements == 0) { + // C++11 value-initialization for the scalar. + return EmitNullValue(E->getType()); + } + // We have a scalar in braces. Just use the first element. + return Visit(E->getInit(0)); + } + + unsigned ResElts = VType->getNumElements(); + + // Loop over initializers collecting the Value for each, and remembering + // whether the source was swizzle (ExtVectorElementExpr). This will allow + // us to fold the shuffle for the swizzle into the shuffle for the vector + // initializer, since LLVM optimizers generally do not want to touch + // shuffles. + unsigned CurIdx = 0; + bool VIsUndefShuffle = false; + llvm::Value *V = llvm::UndefValue::get(VType); + for (unsigned i = 0; i != NumInitElements; ++i) { + Expr *IE = E->getInit(i); + Value *Init = Visit(IE); + SmallVector<llvm::Constant*, 16> Args; + + llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType()); + + // Handle scalar elements. If the scalar initializer is actually one + // element of a different vector of the same width, use shuffle instead of + // extract+insert. + if (!VVT) { + if (isa<ExtVectorElementExpr>(IE)) { + llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init); + + if (EI->getVectorOperandType()->getNumElements() == ResElts) { + llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand()); + Value *LHS = nullptr, *RHS = nullptr; + if (CurIdx == 0) { + // insert into undef -> shuffle (src, undef) + // shufflemask must use an i32 + Args.push_back(getAsInt32(C, CGF.Int32Ty)); + Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); + + LHS = EI->getVectorOperand(); + RHS = V; + VIsUndefShuffle = true; + } else if (VIsUndefShuffle) { + // insert into undefshuffle && size match -> shuffle (v, src) + llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V); + for (unsigned j = 0; j != CurIdx; ++j) + Args.push_back(getMaskElt(SVV, j, 0, CGF.Int32Ty)); + Args.push_back(Builder.getInt32(ResElts + C->getZExtValue())); + Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); + + LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0); + RHS = EI->getVectorOperand(); + VIsUndefShuffle = false; + } + if (!Args.empty()) { + llvm::Constant *Mask = llvm::ConstantVector::get(Args); + V = Builder.CreateShuffleVector(LHS, RHS, Mask); + ++CurIdx; + continue; + } + } + } + V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx), + "vecinit"); + VIsUndefShuffle = false; + ++CurIdx; + continue; + } + + unsigned InitElts = VVT->getNumElements(); + + // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's + // input is the same width as the vector being constructed, generate an + // optimized shuffle of the swizzle input into the result. + unsigned Offset = (CurIdx == 0) ? 0 : ResElts; + if (isa<ExtVectorElementExpr>(IE)) { + llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init); + Value *SVOp = SVI->getOperand(0); + llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType()); + + if (OpTy->getNumElements() == ResElts) { + for (unsigned j = 0; j != CurIdx; ++j) { + // If the current vector initializer is a shuffle with undef, merge + // this shuffle directly into it. + if (VIsUndefShuffle) { + Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0, + CGF.Int32Ty)); + } else { + Args.push_back(Builder.getInt32(j)); + } + } + for (unsigned j = 0, je = InitElts; j != je; ++j) + Args.push_back(getMaskElt(SVI, j, Offset, CGF.Int32Ty)); + Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); + + if (VIsUndefShuffle) + V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0); + + Init = SVOp; + } + } + + // Extend init to result vector length, and then shuffle its contribution + // to the vector initializer into V. + if (Args.empty()) { + for (unsigned j = 0; j != InitElts; ++j) + Args.push_back(Builder.getInt32(j)); + Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); + llvm::Constant *Mask = llvm::ConstantVector::get(Args); + Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT), + Mask, "vext"); + + Args.clear(); + for (unsigned j = 0; j != CurIdx; ++j) + Args.push_back(Builder.getInt32(j)); + for (unsigned j = 0; j != InitElts; ++j) + Args.push_back(Builder.getInt32(j+Offset)); + Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); + } + + // If V is undef, make sure it ends up on the RHS of the shuffle to aid + // merging subsequent shuffles into this one. + if (CurIdx == 0) + std::swap(V, Init); + llvm::Constant *Mask = llvm::ConstantVector::get(Args); + V = Builder.CreateShuffleVector(V, Init, Mask, "vecinit"); + VIsUndefShuffle = isa<llvm::UndefValue>(Init); + CurIdx += InitElts; + } + + // FIXME: evaluate codegen vs. shuffling against constant null vector. + // Emit remaining default initializers. + llvm::Type *EltTy = VType->getElementType(); + + // Emit remaining default initializers + for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) { + Value *Idx = Builder.getInt32(CurIdx); + llvm::Value *Init = llvm::Constant::getNullValue(EltTy); + V = Builder.CreateInsertElement(V, Init, Idx, "vecinit"); + } + return V; +} + +bool CodeGenFunction::ShouldNullCheckClassCastValue(const CastExpr *CE) { + const Expr *E = CE->getSubExpr(); + + if (CE->getCastKind() == CK_UncheckedDerivedToBase) + return false; + + if (isa<CXXThisExpr>(E->IgnoreParens())) { + // We always assume that 'this' is never null. + return false; + } + + if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) { + // And that glvalue casts are never null. + if (ICE->getValueKind() != VK_RValue) + return false; + } + + return true; +} + +// VisitCastExpr - Emit code for an explicit or implicit cast. Implicit casts +// have to handle a more broad range of conversions than explicit casts, as they +// handle things like function to ptr-to-function decay etc. +Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { + Expr *E = CE->getSubExpr(); + QualType DestTy = CE->getType(); + CastKind Kind = CE->getCastKind(); + + // These cases are generally not written to ignore the result of + // evaluating their sub-expressions, so we clear this now. + bool Ignored = TestAndClearIgnoreResultAssign(); + + // Since almost all cast kinds apply to scalars, this switch doesn't have + // a default case, so the compiler will warn on a missing case. The cases + // are in the same order as in the CastKind enum. + switch (Kind) { + case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); + case CK_BuiltinFnToFnPtr: + llvm_unreachable("builtin functions are handled elsewhere"); + + case CK_LValueBitCast: + case CK_ObjCObjectLValueCast: { + Address Addr = EmitLValue(E).getAddress(); + Addr = Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(DestTy)); + LValue LV = CGF.MakeAddrLValue(Addr, DestTy); + return EmitLoadOfLValue(LV, CE->getExprLoc()); + } + + case CK_LValueToRValueBitCast: { + LValue SourceLVal = CGF.EmitLValue(E); + Address Addr = Builder.CreateElementBitCast(SourceLVal.getAddress(), + CGF.ConvertTypeForMem(DestTy)); + LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy); + DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo()); + return EmitLoadOfLValue(DestLV, CE->getExprLoc()); + } + + case CK_CPointerToObjCPointerCast: + case CK_BlockPointerToObjCPointerCast: + case CK_AnyPointerToBlockPointerCast: + case CK_BitCast: { + Value *Src = Visit(const_cast<Expr*>(E)); + llvm::Type *SrcTy = Src->getType(); + llvm::Type *DstTy = ConvertType(DestTy); + if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() && + SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) { + llvm_unreachable("wrong cast for pointers in different address spaces" + "(must be an address space cast)!"); + } + + if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast)) { + if (auto PT = DestTy->getAs<PointerType>()) + CGF.EmitVTablePtrCheckForCast(PT->getPointeeType(), Src, + /*MayBeNull=*/true, + CodeGenFunction::CFITCK_UnrelatedCast, + CE->getBeginLoc()); + } + + if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) { + const QualType SrcType = E->getType(); + + if (SrcType.mayBeNotDynamicClass() && DestTy.mayBeDynamicClass()) { + // Casting to pointer that could carry dynamic information (provided by + // invariant.group) requires launder. + Src = Builder.CreateLaunderInvariantGroup(Src); + } else if (SrcType.mayBeDynamicClass() && DestTy.mayBeNotDynamicClass()) { + // Casting to pointer that does not carry dynamic information (provided + // by invariant.group) requires stripping it. Note that we don't do it + // if the source could not be dynamic type and destination could be + // dynamic because dynamic information is already laundered. It is + // because launder(strip(src)) == launder(src), so there is no need to + // add extra strip before launder. + Src = Builder.CreateStripInvariantGroup(Src); + } + } + + // Update heapallocsite metadata when there is an explicit cast. + if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(Src)) + if (CI->getMetadata("heapallocsite") && isa<ExplicitCastExpr>(CE)) + CGF.getDebugInfo()-> + addHeapAllocSiteMetadata(CI, CE->getType(), CE->getExprLoc()); + + return Builder.CreateBitCast(Src, DstTy); + } + case CK_AddressSpaceConversion: { + Expr::EvalResult Result; + if (E->EvaluateAsRValue(Result, CGF.getContext()) && + Result.Val.isNullPointer()) { + // If E has side effect, it is emitted even if its final result is a + // null pointer. In that case, a DCE pass should be able to + // eliminate the useless instructions emitted during translating E. + if (Result.HasSideEffects) + Visit(E); + return CGF.CGM.getNullPointer(cast<llvm::PointerType>( + ConvertType(DestTy)), DestTy); + } + // Since target may map different address spaces in AST to the same address + // space, an address space conversion may end up as a bitcast. + return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast( + CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(), + DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy)); + } + case CK_AtomicToNonAtomic: + case CK_NonAtomicToAtomic: + case CK_NoOp: + case CK_UserDefinedConversion: + return Visit(const_cast<Expr*>(E)); + + case CK_BaseToDerived: { + const CXXRecordDecl *DerivedClassDecl = DestTy->getPointeeCXXRecordDecl(); + assert(DerivedClassDecl && "BaseToDerived arg isn't a C++ object pointer!"); + + Address Base = CGF.EmitPointerWithAlignment(E); + Address Derived = + CGF.GetAddressOfDerivedClass(Base, DerivedClassDecl, + CE->path_begin(), CE->path_end(), + CGF.ShouldNullCheckClassCastValue(CE)); + + // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is + // performed and the object is not of the derived type. + if (CGF.sanitizePerformTypeCheck()) + CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(), + Derived.getPointer(), DestTy->getPointeeType()); + + if (CGF.SanOpts.has(SanitizerKind::CFIDerivedCast)) + CGF.EmitVTablePtrCheckForCast( + DestTy->getPointeeType(), Derived.getPointer(), + /*MayBeNull=*/true, CodeGenFunction::CFITCK_DerivedCast, + CE->getBeginLoc()); + + return Derived.getPointer(); + } + case CK_UncheckedDerivedToBase: + case CK_DerivedToBase: { + // The EmitPointerWithAlignment path does this fine; just discard + // the alignment. + return CGF.EmitPointerWithAlignment(CE).getPointer(); + } + + case CK_Dynamic: { + Address V = CGF.EmitPointerWithAlignment(E); + const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE); + return CGF.EmitDynamicCast(V, DCE); + } + + case CK_ArrayToPointerDecay: + return CGF.EmitArrayToPointerDecay(E).getPointer(); + case CK_FunctionToPointerDecay: + return EmitLValue(E).getPointer(); + + case CK_NullToPointer: + if (MustVisitNullValue(E)) + CGF.EmitIgnoredExpr(E); + + return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)), + DestTy); + + case CK_NullToMemberPointer: { + if (MustVisitNullValue(E)) + CGF.EmitIgnoredExpr(E); + + const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>(); + return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT); + } + + case CK_ReinterpretMemberPointer: + case CK_BaseToDerivedMemberPointer: + case CK_DerivedToBaseMemberPointer: { + Value *Src = Visit(E); + + // Note that the AST doesn't distinguish between checked and + // unchecked member pointer conversions, so we always have to + // implement checked conversions here. This is inefficient when + // actual control flow may be required in order to perform the + // check, which it is for data member pointers (but not member + // function pointers on Itanium and ARM). + return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src); + } + + case CK_ARCProduceObject: + return CGF.EmitARCRetainScalarExpr(E); + case CK_ARCConsumeObject: + return CGF.EmitObjCConsumeObject(E->getType(), Visit(E)); + case CK_ARCReclaimReturnedObject: + return CGF.EmitARCReclaimReturnedObject(E, /*allowUnsafe*/ Ignored); + case CK_ARCExtendBlockObject: + return CGF.EmitARCExtendBlockObject(E); + + case CK_CopyAndAutoreleaseBlockObject: + return CGF.EmitBlockCopyAndAutorelease(Visit(E), E->getType()); + + case CK_FloatingRealToComplex: + case CK_FloatingComplexCast: + case CK_IntegralRealToComplex: + case CK_IntegralComplexCast: + case CK_IntegralComplexToFloatingComplex: + case CK_FloatingComplexToIntegralComplex: + case CK_ConstructorConversion: + case CK_ToUnion: + llvm_unreachable("scalar cast to non-scalar value"); + + case CK_LValueToRValue: + assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy)); + assert(E->isGLValue() && "lvalue-to-rvalue applied to r-value!"); + return Visit(const_cast<Expr*>(E)); + + case CK_IntegralToPointer: { + Value *Src = Visit(const_cast<Expr*>(E)); + + // First, convert to the correct width so that we control the kind of + // extension. + auto DestLLVMTy = ConvertType(DestTy); + llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DestLLVMTy); + bool InputSigned = E->getType()->isSignedIntegerOrEnumerationType(); + llvm::Value* IntResult = + Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv"); + + auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy); + + if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) { + // Going from integer to pointer that could be dynamic requires reloading + // dynamic information from invariant.group. + if (DestTy.mayBeDynamicClass()) + IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr); + } + return IntToPtr; + } + case CK_PointerToIntegral: { + assert(!DestTy->isBooleanType() && "bool should use PointerToBool"); + auto *PtrExpr = Visit(E); + + if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) { + const QualType SrcType = E->getType(); + + // Casting to integer requires stripping dynamic information as it does + // not carries it. + if (SrcType.mayBeDynamicClass()) + PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr); + } + + return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy)); + } + case CK_ToVoid: { + CGF.EmitIgnoredExpr(E); + return nullptr; + } + case CK_VectorSplat: { + llvm::Type *DstTy = ConvertType(DestTy); + Value *Elt = Visit(const_cast<Expr*>(E)); + // Splat the element across to all elements + unsigned NumElements = DstTy->getVectorNumElements(); + return Builder.CreateVectorSplat(NumElements, Elt, "splat"); + } + + case CK_FixedPointCast: + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc()); + + case CK_FixedPointToBoolean: + assert(E->getType()->isFixedPointType() && + "Expected src type to be fixed point type"); + assert(DestTy->isBooleanType() && "Expected dest type to be boolean type"); + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc()); + + case CK_FixedPointToIntegral: + assert(E->getType()->isFixedPointType() && + "Expected src type to be fixed point type"); + assert(DestTy->isIntegerType() && "Expected dest type to be an integer"); + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc()); + + case CK_IntegralToFixedPoint: + assert(E->getType()->isIntegerType() && + "Expected src type to be an integer"); + assert(DestTy->isFixedPointType() && + "Expected dest type to be fixed point type"); + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc()); + + case CK_IntegralCast: { + ScalarConversionOpts Opts; + if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) { + if (!ICE->isPartOfExplicitCast()) + Opts = ScalarConversionOpts(CGF.SanOpts); + } + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc(), Opts); + } + case CK_IntegralToFloating: + case CK_FloatingToIntegral: + case CK_FloatingCast: + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc()); + case CK_BooleanToSignedIntegral: { + ScalarConversionOpts Opts; + Opts.TreatBooleanAsSigned = true; + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc(), Opts); + } + case CK_IntegralToBoolean: + return EmitIntToBoolConversion(Visit(E)); + case CK_PointerToBoolean: + return EmitPointerToBoolConversion(Visit(E), E->getType()); + case CK_FloatingToBoolean: + return EmitFloatToBoolConversion(Visit(E)); + case CK_MemberPointerToBoolean: { + llvm::Value *MemPtr = Visit(E); + const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>(); + return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT); + } + + case CK_FloatingComplexToReal: + case CK_IntegralComplexToReal: + return CGF.EmitComplexExpr(E, false, true).first; + + case CK_FloatingComplexToBoolean: + case CK_IntegralComplexToBoolean: { + CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E); + + // TODO: kill this function off, inline appropriate case here + return EmitComplexToScalarConversion(V, E->getType(), DestTy, + CE->getExprLoc()); + } + + case CK_ZeroToOCLOpaqueType: { + assert((DestTy->isEventT() || DestTy->isQueueT() || + DestTy->isOCLIntelSubgroupAVCType()) && + "CK_ZeroToOCLEvent cast on non-event type"); + return llvm::Constant::getNullValue(ConvertType(DestTy)); + } + + case CK_IntToOCLSampler: + return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF); + + } // end of switch + + llvm_unreachable("unknown scalar cast"); +} + +Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) { + CodeGenFunction::StmtExprEvaluation eval(CGF); + Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), + !E->getType()->isVoidType()); + if (!RetAlloca.isValid()) + return nullptr; + return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType()), + E->getExprLoc()); +} + +Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { + CGF.enterFullExpression(E); + CodeGenFunction::RunCleanupsScope Scope(CGF); + Value *V = Visit(E->getSubExpr()); + // Defend against dominance problems caused by jumps out of expression + // evaluation through the shared cleanup block. + Scope.ForceCleanup({&V}); + return V; +} + +//===----------------------------------------------------------------------===// +// Unary Operators +//===----------------------------------------------------------------------===// + +static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, + llvm::Value *InVal, bool IsInc) { + BinOpInfo BinOp; + BinOp.LHS = InVal; + BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false); + BinOp.Ty = E->getType(); + BinOp.Opcode = IsInc ? BO_Add : BO_Sub; + // FIXME: once UnaryOperator carries FPFeatures, copy it here. + BinOp.E = E; + return BinOp; +} + +llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior( + const UnaryOperator *E, llvm::Value *InVal, bool IsInc) { + llvm::Value *Amount = + llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, true); + StringRef Name = IsInc ? "inc" : "dec"; + switch (CGF.getLangOpts().getSignedOverflowBehavior()) { + case LangOptions::SOB_Defined: + return Builder.CreateAdd(InVal, Amount, Name); + case LangOptions::SOB_Undefined: + if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) + return Builder.CreateNSWAdd(InVal, Amount, Name); + LLVM_FALLTHROUGH; + case LangOptions::SOB_Trapping: + if (!E->canOverflow()) + return Builder.CreateNSWAdd(InVal, Amount, Name); + return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, InVal, IsInc)); + } + llvm_unreachable("Unknown SignedOverflowBehaviorTy"); +} + +llvm::Value * +ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, + bool isInc, bool isPre) { + + QualType type = E->getSubExpr()->getType(); + llvm::PHINode *atomicPHI = nullptr; + llvm::Value *value; + llvm::Value *input; + + int amount = (isInc ? 1 : -1); + bool isSubtraction = !isInc; + + if (const AtomicType *atomicTy = type->getAs<AtomicType>()) { + type = atomicTy->getValueType(); + if (isInc && type->isBooleanType()) { + llvm::Value *True = CGF.EmitToMemory(Builder.getTrue(), type); + if (isPre) { + Builder.CreateStore(True, LV.getAddress(), LV.isVolatileQualified()) + ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent); + return Builder.getTrue(); + } + // For atomic bool increment, we just store true and return it for + // preincrement, do an atomic swap with true for postincrement + return Builder.CreateAtomicRMW( + llvm::AtomicRMWInst::Xchg, LV.getPointer(), True, + llvm::AtomicOrdering::SequentiallyConsistent); + } + // Special case for atomic increment / decrement on integers, emit + // atomicrmw instructions. We skip this if we want to be doing overflow + // checking, and fall into the slow path with the atomic cmpxchg loop. + if (!type->isBooleanType() && type->isIntegerType() && + !(type->isUnsignedIntegerType() && + CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) && + CGF.getLangOpts().getSignedOverflowBehavior() != + LangOptions::SOB_Trapping) { + llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add : + llvm::AtomicRMWInst::Sub; + llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add : + llvm::Instruction::Sub; + llvm::Value *amt = CGF.EmitToMemory( + llvm::ConstantInt::get(ConvertType(type), 1, true), type); + llvm::Value *old = Builder.CreateAtomicRMW(aop, + LV.getPointer(), amt, llvm::AtomicOrdering::SequentiallyConsistent); + return isPre ? Builder.CreateBinOp(op, old, amt) : old; + } + value = EmitLoadOfLValue(LV, E->getExprLoc()); + input = value; + // For every other atomic operation, we need to emit a load-op-cmpxchg loop + llvm::BasicBlock *startBB = Builder.GetInsertBlock(); + llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn); + value = CGF.EmitToMemory(value, type); + Builder.CreateBr(opBB); + Builder.SetInsertPoint(opBB); + atomicPHI = Builder.CreatePHI(value->getType(), 2); + atomicPHI->addIncoming(value, startBB); + value = atomicPHI; + } else { + value = EmitLoadOfLValue(LV, E->getExprLoc()); + input = value; + } + + // Special case of integer increment that we have to check first: bool++. + // Due to promotion rules, we get: + // bool++ -> bool = bool + 1 + // -> bool = (int)bool + 1 + // -> bool = ((int)bool + 1 != 0) + // An interesting aspect of this is that increment is always true. + // Decrement does not have this property. + if (isInc && type->isBooleanType()) { + value = Builder.getTrue(); + + // Most common case by far: integer increment. + } else if (type->isIntegerType()) { + // Note that signed integer inc/dec with width less than int can't + // overflow because of promotion rules; we're just eliding a few steps here. + if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) { + value = EmitIncDecConsiderOverflowBehavior(E, value, isInc); + } else if (E->canOverflow() && type->isUnsignedIntegerType() && + CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) { + value = + EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, value, isInc)); + } else { + llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true); + value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec"); + } + + // Next most common: pointer increment. + } else if (const PointerType *ptr = type->getAs<PointerType>()) { + QualType type = ptr->getPointeeType(); + + // VLA types don't have constant size. + if (const VariableArrayType *vla + = CGF.getContext().getAsVariableArrayType(type)) { + llvm::Value *numElts = CGF.getVLASize(vla).NumElts; + if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize"); + if (CGF.getLangOpts().isSignedOverflowDefined()) + value = Builder.CreateGEP(value, numElts, "vla.inc"); + else + value = CGF.EmitCheckedInBoundsGEP( + value, numElts, /*SignedIndices=*/false, isSubtraction, + E->getExprLoc(), "vla.inc"); + + // Arithmetic on function pointers (!) is just +-1. + } else if (type->isFunctionType()) { + llvm::Value *amt = Builder.getInt32(amount); + + value = CGF.EmitCastToVoidPtr(value); + if (CGF.getLangOpts().isSignedOverflowDefined()) + value = Builder.CreateGEP(value, amt, "incdec.funcptr"); + else + value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false, + isSubtraction, E->getExprLoc(), + "incdec.funcptr"); + value = Builder.CreateBitCast(value, input->getType()); + + // For everything else, we can just do a simple increment. + } else { + llvm::Value *amt = Builder.getInt32(amount); + if (CGF.getLangOpts().isSignedOverflowDefined()) + value = Builder.CreateGEP(value, amt, "incdec.ptr"); + else + value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false, + isSubtraction, E->getExprLoc(), + "incdec.ptr"); + } + + // Vector increment/decrement. + } else if (type->isVectorType()) { + if (type->hasIntegerRepresentation()) { + llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount); + + value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec"); + } else { + value = Builder.CreateFAdd( + value, + llvm::ConstantFP::get(value->getType(), amount), + isInc ? "inc" : "dec"); + } + + // Floating point. + } else if (type->isRealFloatingType()) { + // Add the inc/dec to the real part. + llvm::Value *amt; + + if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { + // Another special case: half FP increment should be done via float + if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) { + value = Builder.CreateCall( + CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, + CGF.CGM.FloatTy), + input, "incdec.conv"); + } else { + value = Builder.CreateFPExt(input, CGF.CGM.FloatTy, "incdec.conv"); + } + } + + if (value->getType()->isFloatTy()) + amt = llvm::ConstantFP::get(VMContext, + llvm::APFloat(static_cast<float>(amount))); + else if (value->getType()->isDoubleTy()) + amt = llvm::ConstantFP::get(VMContext, + llvm::APFloat(static_cast<double>(amount))); + else { + // Remaining types are Half, LongDouble or __float128. Convert from float. + llvm::APFloat F(static_cast<float>(amount)); + bool ignored; + const llvm::fltSemantics *FS; + // Don't use getFloatTypeSemantics because Half isn't + // necessarily represented using the "half" LLVM type. + if (value->getType()->isFP128Ty()) + FS = &CGF.getTarget().getFloat128Format(); + else if (value->getType()->isHalfTy()) + FS = &CGF.getTarget().getHalfFormat(); + else + FS = &CGF.getTarget().getLongDoubleFormat(); + F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored); + amt = llvm::ConstantFP::get(VMContext, F); + } + value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec"); + + if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { + if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) { + value = Builder.CreateCall( + CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, + CGF.CGM.FloatTy), + value, "incdec.conv"); + } else { + value = Builder.CreateFPTrunc(value, input->getType(), "incdec.conv"); + } + } + + // Objective-C pointer types. + } else { + const ObjCObjectPointerType *OPT = type->castAs<ObjCObjectPointerType>(); + value = CGF.EmitCastToVoidPtr(value); + + CharUnits size = CGF.getContext().getTypeSizeInChars(OPT->getObjectType()); + if (!isInc) size = -size; + llvm::Value *sizeValue = + llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity()); + + if (CGF.getLangOpts().isSignedOverflowDefined()) + value = Builder.CreateGEP(value, sizeValue, "incdec.objptr"); + else + value = CGF.EmitCheckedInBoundsGEP(value, sizeValue, + /*SignedIndices=*/false, isSubtraction, + E->getExprLoc(), "incdec.objptr"); + value = Builder.CreateBitCast(value, input->getType()); + } + + if (atomicPHI) { + llvm::BasicBlock *curBlock = Builder.GetInsertBlock(); + llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn); + auto Pair = CGF.EmitAtomicCompareExchange( + LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc()); + llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type); + llvm::Value *success = Pair.second; + atomicPHI->addIncoming(old, curBlock); + Builder.CreateCondBr(success, contBB, atomicPHI->getParent()); + Builder.SetInsertPoint(contBB); + return isPre ? value : input; + } + + // Store the updated result through the lvalue. + if (LV.isBitField()) + CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value); + else + CGF.EmitStoreThroughLValue(RValue::get(value), LV); + + // If this is a postinc, return the value read from memory, otherwise use the + // updated value. + return isPre ? value : input; +} + + + +Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { + TestAndClearIgnoreResultAssign(); + Value *Op = Visit(E->getSubExpr()); + + // Generate a unary FNeg for FP ops. + if (Op->getType()->isFPOrFPVectorTy()) + return Builder.CreateFNeg(Op, "fneg"); + + // Emit unary minus with EmitSub so we handle overflow cases etc. + BinOpInfo BinOp; + BinOp.RHS = Op; + BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType()); + BinOp.Ty = E->getType(); + BinOp.Opcode = BO_Sub; + // FIXME: once UnaryOperator carries FPFeatures, copy it here. + BinOp.E = E; + return EmitSub(BinOp); +} + +Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) { + TestAndClearIgnoreResultAssign(); + Value *Op = Visit(E->getSubExpr()); + return Builder.CreateNot(Op, "neg"); +} + +Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) { + // Perform vector logical not on comparison with zero vector. + if (E->getType()->isExtVectorType()) { + Value *Oper = Visit(E->getSubExpr()); + Value *Zero = llvm::Constant::getNullValue(Oper->getType()); + Value *Result; + if (Oper->getType()->isFPOrFPVectorTy()) + Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp"); + else + Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp"); + return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext"); + } + + // Compare operand to zero. + Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr()); + + // Invert value. + // TODO: Could dynamically modify easy computations here. For example, if + // the operand is an icmp ne, turn into icmp eq. + BoolVal = Builder.CreateNot(BoolVal, "lnot"); + + // ZExt result to the expr type. + return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext"); +} + +Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) { + // Try folding the offsetof to a constant. + Expr::EvalResult EVResult; + if (E->EvaluateAsInt(EVResult, CGF.getContext())) { + llvm::APSInt Value = EVResult.Val.getInt(); + return Builder.getInt(Value); + } + + // Loop over the components of the offsetof to compute the value. + unsigned n = E->getNumComponents(); + llvm::Type* ResultType = ConvertType(E->getType()); + llvm::Value* Result = llvm::Constant::getNullValue(ResultType); + QualType CurrentType = E->getTypeSourceInfo()->getType(); + for (unsigned i = 0; i != n; ++i) { + OffsetOfNode ON = E->getComponent(i); + llvm::Value *Offset = nullptr; + switch (ON.getKind()) { + case OffsetOfNode::Array: { + // Compute the index + Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex()); + llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr); + bool IdxSigned = IdxExpr->getType()->isSignedIntegerOrEnumerationType(); + Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned, "conv"); + + // Save the element type + CurrentType = + CGF.getContext().getAsArrayType(CurrentType)->getElementType(); + + // Compute the element size + llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType, + CGF.getContext().getTypeSizeInChars(CurrentType).getQuantity()); + + // Multiply out to compute the result + Offset = Builder.CreateMul(Idx, ElemSize); + break; + } + + case OffsetOfNode::Field: { + FieldDecl *MemberDecl = ON.getField(); + RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl(); + const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD); + + // Compute the index of the field in its parent. + unsigned i = 0; + // FIXME: It would be nice if we didn't have to loop here! + for (RecordDecl::field_iterator Field = RD->field_begin(), + FieldEnd = RD->field_end(); + Field != FieldEnd; ++Field, ++i) { + if (*Field == MemberDecl) + break; + } + assert(i < RL.getFieldCount() && "offsetof field in wrong type"); + + // Compute the offset to the field + int64_t OffsetInt = RL.getFieldOffset(i) / + CGF.getContext().getCharWidth(); + Offset = llvm::ConstantInt::get(ResultType, OffsetInt); + + // Save the element type. + CurrentType = MemberDecl->getType(); + break; + } + + case OffsetOfNode::Identifier: + llvm_unreachable("dependent __builtin_offsetof"); + + case OffsetOfNode::Base: { + if (ON.getBase()->isVirtual()) { + CGF.ErrorUnsupported(E, "virtual base in offsetof"); + continue; + } + + RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl(); + const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD); + + // Save the element type. + CurrentType = ON.getBase()->getType(); + + // Compute the offset to the base. + const RecordType *BaseRT = CurrentType->getAs<RecordType>(); + CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl()); + CharUnits OffsetInt = RL.getBaseClassOffset(BaseRD); + Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity()); + break; + } + } + Result = Builder.CreateAdd(Result, Offset); + } + return Result; +} + +/// VisitUnaryExprOrTypeTraitExpr - Return the size or alignment of the type of +/// argument of the sizeof expression as an integer. +Value * +ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr( + const UnaryExprOrTypeTraitExpr *E) { + QualType TypeToSize = E->getTypeOfArgument(); + if (E->getKind() == UETT_SizeOf) { + if (const VariableArrayType *VAT = + CGF.getContext().getAsVariableArrayType(TypeToSize)) { + if (E->isArgumentType()) { + // sizeof(type) - make sure to emit the VLA size. + CGF.EmitVariablyModifiedType(TypeToSize); + } else { + // C99 6.5.3.4p2: If the argument is an expression of type + // VLA, it is evaluated. + CGF.EmitIgnoredExpr(E->getArgumentExpr()); + } + + auto VlaSize = CGF.getVLASize(VAT); + llvm::Value *size = VlaSize.NumElts; + + // Scale the number of non-VLA elements by the non-VLA element size. + CharUnits eltSize = CGF.getContext().getTypeSizeInChars(VlaSize.Type); + if (!eltSize.isOne()) + size = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), size); + + return size; + } + } else if (E->getKind() == UETT_OpenMPRequiredSimdAlign) { + auto Alignment = + CGF.getContext() + .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign( + E->getTypeOfArgument()->getPointeeType())) + .getQuantity(); + return llvm::ConstantInt::get(CGF.SizeTy, Alignment); + } + + // If this isn't sizeof(vla), the result must be constant; use the constant + // folding logic so we don't have to duplicate it here. + return Builder.getInt(E->EvaluateKnownConstInt(CGF.getContext())); +} + +Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) { + Expr *Op = E->getSubExpr(); + if (Op->getType()->isAnyComplexType()) { + // If it's an l-value, load through the appropriate subobject l-value. + // Note that we have to ask E because Op might be an l-value that + // this won't work for, e.g. an Obj-C property. + if (E->isGLValue()) + return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), + E->getExprLoc()).getScalarVal(); + + // Otherwise, calculate and project. + return CGF.EmitComplexExpr(Op, false, true).first; + } + + return Visit(Op); +} + +Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) { + Expr *Op = E->getSubExpr(); + if (Op->getType()->isAnyComplexType()) { + // If it's an l-value, load through the appropriate subobject l-value. + // Note that we have to ask E because Op might be an l-value that + // this won't work for, e.g. an Obj-C property. + if (Op->isGLValue()) + return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), + E->getExprLoc()).getScalarVal(); + + // Otherwise, calculate and project. + return CGF.EmitComplexExpr(Op, true, false).second; + } + + // __imag on a scalar returns zero. Emit the subexpr to ensure side + // effects are evaluated, but not the actual value. + if (Op->isGLValue()) + CGF.EmitLValue(Op); + else + CGF.EmitScalarExpr(Op, true); + return llvm::Constant::getNullValue(ConvertType(E->getType())); +} + +//===----------------------------------------------------------------------===// +// Binary Operators +//===----------------------------------------------------------------------===// + +BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) { + TestAndClearIgnoreResultAssign(); + BinOpInfo Result; + Result.LHS = Visit(E->getLHS()); + Result.RHS = Visit(E->getRHS()); + Result.Ty = E->getType(); + Result.Opcode = E->getOpcode(); + Result.FPFeatures = E->getFPFeatures(); + Result.E = E; + return Result; +} + +LValue ScalarExprEmitter::EmitCompoundAssignLValue( + const CompoundAssignOperator *E, + Value *(ScalarExprEmitter::*Func)(const BinOpInfo &), + Value *&Result) { + QualType LHSTy = E->getLHS()->getType(); + BinOpInfo OpInfo; + + if (E->getComputationResultType()->isAnyComplexType()) + return CGF.EmitScalarCompoundAssignWithComplex(E, Result); + + // Emit the RHS first. __block variables need to have the rhs evaluated + // first, plus this should improve codegen a little. + OpInfo.RHS = Visit(E->getRHS()); + OpInfo.Ty = E->getComputationResultType(); + OpInfo.Opcode = E->getOpcode(); + OpInfo.FPFeatures = E->getFPFeatures(); + OpInfo.E = E; + // Load/convert the LHS. + LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store); + + llvm::PHINode *atomicPHI = nullptr; + if (const AtomicType *atomicTy = LHSTy->getAs<AtomicType>()) { + QualType type = atomicTy->getValueType(); + if (!type->isBooleanType() && type->isIntegerType() && + !(type->isUnsignedIntegerType() && + CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) && + CGF.getLangOpts().getSignedOverflowBehavior() != + LangOptions::SOB_Trapping) { + llvm::AtomicRMWInst::BinOp aop = llvm::AtomicRMWInst::BAD_BINOP; + switch (OpInfo.Opcode) { + // We don't have atomicrmw operands for *, %, /, <<, >> + case BO_MulAssign: case BO_DivAssign: + case BO_RemAssign: + case BO_ShlAssign: + case BO_ShrAssign: + break; + case BO_AddAssign: + aop = llvm::AtomicRMWInst::Add; + break; + case BO_SubAssign: + aop = llvm::AtomicRMWInst::Sub; + break; + case BO_AndAssign: + aop = llvm::AtomicRMWInst::And; + break; + case BO_XorAssign: + aop = llvm::AtomicRMWInst::Xor; + break; + case BO_OrAssign: + aop = llvm::AtomicRMWInst::Or; + break; + default: + llvm_unreachable("Invalid compound assignment type"); + } + if (aop != llvm::AtomicRMWInst::BAD_BINOP) { + llvm::Value *amt = CGF.EmitToMemory( + EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy, + E->getExprLoc()), + LHSTy); + Builder.CreateAtomicRMW(aop, LHSLV.getPointer(), amt, + llvm::AtomicOrdering::SequentiallyConsistent); + return LHSLV; + } + } + // FIXME: For floating point types, we should be saving and restoring the + // floating point environment in the loop. + llvm::BasicBlock *startBB = Builder.GetInsertBlock(); + llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn); + OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc()); + OpInfo.LHS = CGF.EmitToMemory(OpInfo.LHS, type); + Builder.CreateBr(opBB); + Builder.SetInsertPoint(opBB); + atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2); + atomicPHI->addIncoming(OpInfo.LHS, startBB); + OpInfo.LHS = atomicPHI; + } + else + OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc()); + + SourceLocation Loc = E->getExprLoc(); + OpInfo.LHS = + EmitScalarConversion(OpInfo.LHS, LHSTy, E->getComputationLHSType(), Loc); + + // Expand the binary operator. + Result = (this->*Func)(OpInfo); + + // Convert the result back to the LHS type, + // potentially with Implicit Conversion sanitizer check. + Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy, + Loc, ScalarConversionOpts(CGF.SanOpts)); + + if (atomicPHI) { + llvm::BasicBlock *curBlock = Builder.GetInsertBlock(); + llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn); + auto Pair = CGF.EmitAtomicCompareExchange( + LHSLV, RValue::get(atomicPHI), RValue::get(Result), E->getExprLoc()); + llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), LHSTy); + llvm::Value *success = Pair.second; + atomicPHI->addIncoming(old, curBlock); + Builder.CreateCondBr(success, contBB, atomicPHI->getParent()); + Builder.SetInsertPoint(contBB); + return LHSLV; + } + + // Store the result value into the LHS lvalue. Bit-fields are handled + // specially because the result is altered by the store, i.e., [C99 6.5.16p1] + // 'An assignment expression has the value of the left operand after the + // assignment...'. + if (LHSLV.isBitField()) + CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, &Result); + else + CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV); + + return LHSLV; +} + +Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E, + Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) { + bool Ignore = TestAndClearIgnoreResultAssign(); + Value *RHS = nullptr; + LValue LHS = EmitCompoundAssignLValue(E, Func, RHS); + + // If the result is clearly ignored, return now. + if (Ignore) + return nullptr; + + // The result of an assignment in C is the assigned r-value. + if (!CGF.getLangOpts().CPlusPlus) + return RHS; + + // If the lvalue is non-volatile, return the computed value of the assignment. + if (!LHS.isVolatileQualified()) + return RHS; + + // Otherwise, reload the value. + return EmitLoadOfLValue(LHS, E->getExprLoc()); +} + +void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( + const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) { + SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; + + if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) { + Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero), + SanitizerKind::IntegerDivideByZero)); + } + + const auto *BO = cast<BinaryOperator>(Ops.E); + if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) && + Ops.Ty->hasSignedIntegerRepresentation() && + !IsWidenedIntegerOp(CGF.getContext(), BO->getLHS()) && + Ops.mayHaveIntegerOverflow()) { + llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType()); + + llvm::Value *IntMin = + Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth())); + llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL); + + llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin); + llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne); + llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or"); + Checks.push_back( + std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow)); + } + + if (Checks.size() > 0) + EmitBinOpCheck(Checks, Ops); +} + +Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { + { + CodeGenFunction::SanitizerScope SanScope(&CGF); + if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) || + CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) && + Ops.Ty->isIntegerType() && + (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) { + llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); + EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true); + } else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) && + Ops.Ty->isRealFloatingType() && + Ops.mayHaveFloatDivisionByZero()) { + llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); + llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero); + EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero), + Ops); + } + } + + if (Ops.LHS->getType()->isFPOrFPVectorTy()) { + llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div"); + if (CGF.getLangOpts().OpenCL && + !CGF.CGM.getCodeGenOpts().CorrectlyRoundedDivSqrt) { + // OpenCL v1.1 s7.4: minimum accuracy of single precision / is 2.5ulp + // OpenCL v1.2 s5.6.4.2: The -cl-fp32-correctly-rounded-divide-sqrt + // build option allows an application to specify that single precision + // floating-point divide (x/y and 1/x) and sqrt used in the program + // source are correctly rounded. + llvm::Type *ValTy = Val->getType(); + if (ValTy->isFloatTy() || + (isa<llvm::VectorType>(ValTy) && + cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy())) + CGF.SetFPAccuracy(Val, 2.5); + } + return Val; + } + else if (Ops.Ty->hasUnsignedIntegerRepresentation()) + return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div"); + else + return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div"); +} + +Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) { + // Rem in C can't be a floating point type: C99 6.5.5p2. + if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) || + CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) && + Ops.Ty->isIntegerType() && + (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) { + CodeGenFunction::SanitizerScope SanScope(&CGF); + llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); + EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false); + } + + if (Ops.Ty->hasUnsignedIntegerRepresentation()) + return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem"); + else + return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem"); +} + +Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { + unsigned IID; + unsigned OpID = 0; + + bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType(); + switch (Ops.Opcode) { + case BO_Add: + case BO_AddAssign: + OpID = 1; + IID = isSigned ? llvm::Intrinsic::sadd_with_overflow : + llvm::Intrinsic::uadd_with_overflow; + break; + case BO_Sub: + case BO_SubAssign: + OpID = 2; + IID = isSigned ? llvm::Intrinsic::ssub_with_overflow : + llvm::Intrinsic::usub_with_overflow; + break; + case BO_Mul: + case BO_MulAssign: + OpID = 3; + IID = isSigned ? llvm::Intrinsic::smul_with_overflow : + llvm::Intrinsic::umul_with_overflow; + break; + default: + llvm_unreachable("Unsupported operation for overflow detection"); + } + OpID <<= 1; + if (isSigned) + OpID |= 1; + + CodeGenFunction::SanitizerScope SanScope(&CGF); + llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty); + + llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy); + + Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS}); + Value *result = Builder.CreateExtractValue(resultAndOverflow, 0); + Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1); + + // Handle overflow with llvm.trap if no custom handler has been specified. + const std::string *handlerName = + &CGF.getLangOpts().OverflowHandler; + if (handlerName->empty()) { + // If the signed-integer-overflow sanitizer is enabled, emit a call to its + // runtime. Otherwise, this is a -ftrapv check, so just emit a trap. + if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) { + llvm::Value *NotOverflow = Builder.CreateNot(overflow); + SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow + : SanitizerKind::UnsignedIntegerOverflow; + EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops); + } else + CGF.EmitTrapCheck(Builder.CreateNot(overflow)); + return result; + } + + // Branch in case of overflow. + llvm::BasicBlock *initialBB = Builder.GetInsertBlock(); + llvm::BasicBlock *continueBB = + CGF.createBasicBlock("nooverflow", CGF.CurFn, initialBB->getNextNode()); + llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn); + + Builder.CreateCondBr(overflow, overflowBB, continueBB); + + // If an overflow handler is set, then we want to call it and then use its + // result, if it returns. + Builder.SetInsertPoint(overflowBB); + + // Get the overflow handler. + llvm::Type *Int8Ty = CGF.Int8Ty; + llvm::Type *argTypes[] = { CGF.Int64Ty, CGF.Int64Ty, Int8Ty, Int8Ty }; + llvm::FunctionType *handlerTy = + llvm::FunctionType::get(CGF.Int64Ty, argTypes, true); + llvm::FunctionCallee handler = + CGF.CGM.CreateRuntimeFunction(handlerTy, *handlerName); + + // Sign extend the args to 64-bit, so that we can use the same handler for + // all types of overflow. + llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.Int64Ty); + llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.Int64Ty); + + // Call the handler with the two arguments, the operation, and the size of + // the result. + llvm::Value *handlerArgs[] = { + lhs, + rhs, + Builder.getInt8(OpID), + Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth()) + }; + llvm::Value *handlerResult = + CGF.EmitNounwindRuntimeCall(handler, handlerArgs); + + // Truncate the result back to the desired size. + handlerResult = Builder.CreateTrunc(handlerResult, opTy); + Builder.CreateBr(continueBB); + + Builder.SetInsertPoint(continueBB); + llvm::PHINode *phi = Builder.CreatePHI(opTy, 2); + phi->addIncoming(result, initialBB); + phi->addIncoming(handlerResult, overflowBB); + + return phi; +} + +/// Emit pointer + index arithmetic. +static Value *emitPointerArithmetic(CodeGenFunction &CGF, + const BinOpInfo &op, + bool isSubtraction) { + // Must have binary (not unary) expr here. Unary pointer + // increment/decrement doesn't use this path. + const BinaryOperator *expr = cast<BinaryOperator>(op.E); + + Value *pointer = op.LHS; + Expr *pointerOperand = expr->getLHS(); + Value *index = op.RHS; + Expr *indexOperand = expr->getRHS(); + + // In a subtraction, the LHS is always the pointer. + if (!isSubtraction && !pointer->getType()->isPointerTy()) { + std::swap(pointer, index); + std::swap(pointerOperand, indexOperand); + } + + bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType(); + + unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth(); + auto &DL = CGF.CGM.getDataLayout(); + auto PtrTy = cast<llvm::PointerType>(pointer->getType()); + + // Some versions of glibc and gcc use idioms (particularly in their malloc + // routines) that add a pointer-sized integer (known to be a pointer value) + // to a null pointer in order to cast the value back to an integer or as + // part of a pointer alignment algorithm. This is undefined behavior, but + // we'd like to be able to compile programs that use it. + // + // Normally, we'd generate a GEP with a null-pointer base here in response + // to that code, but it's also UB to dereference a pointer created that + // way. Instead (as an acknowledged hack to tolerate the idiom) we will + // generate a direct cast of the integer value to a pointer. + // + // The idiom (p = nullptr + N) is not met if any of the following are true: + // + // The operation is subtraction. + // The index is not pointer-sized. + // The pointer type is not byte-sized. + // + if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(), + op.Opcode, + expr->getLHS(), + expr->getRHS())) + return CGF.Builder.CreateIntToPtr(index, pointer->getType()); + + if (width != DL.getTypeSizeInBits(PtrTy)) { + // Zero-extend or sign-extend the pointer value according to + // whether the index is signed or not. + index = CGF.Builder.CreateIntCast(index, DL.getIntPtrType(PtrTy), isSigned, + "idx.ext"); + } + + // If this is subtraction, negate the index. + if (isSubtraction) + index = CGF.Builder.CreateNeg(index, "idx.neg"); + + if (CGF.SanOpts.has(SanitizerKind::ArrayBounds)) + CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(), + /*Accessed*/ false); + + const PointerType *pointerType + = pointerOperand->getType()->getAs<PointerType>(); + if (!pointerType) { + QualType objectType = pointerOperand->getType() + ->castAs<ObjCObjectPointerType>() + ->getPointeeType(); + llvm::Value *objectSize + = CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(objectType)); + + index = CGF.Builder.CreateMul(index, objectSize); + + Value *result = CGF.Builder.CreateBitCast(pointer, CGF.VoidPtrTy); + result = CGF.Builder.CreateGEP(result, index, "add.ptr"); + return CGF.Builder.CreateBitCast(result, pointer->getType()); + } + + QualType elementType = pointerType->getPointeeType(); + if (const VariableArrayType *vla + = CGF.getContext().getAsVariableArrayType(elementType)) { + // The element count here is the total number of non-VLA elements. + llvm::Value *numElements = CGF.getVLASize(vla).NumElts; + + // Effectively, the multiply by the VLA size is part of the GEP. + // GEP indexes are signed, and scaling an index isn't permitted to + // signed-overflow, so we use the same semantics for our explicit + // multiply. We suppress this if overflow is not undefined behavior. + if (CGF.getLangOpts().isSignedOverflowDefined()) { + index = CGF.Builder.CreateMul(index, numElements, "vla.index"); + pointer = CGF.Builder.CreateGEP(pointer, index, "add.ptr"); + } else { + index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index"); + pointer = + CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction, + op.E->getExprLoc(), "add.ptr"); + } + return pointer; + } + + // Explicitly handle GNU void* and function pointer arithmetic extensions. The + // GNU void* casts amount to no-ops since our void* type is i8*, but this is + // future proof. + if (elementType->isVoidType() || elementType->isFunctionType()) { + Value *result = CGF.Builder.CreateBitCast(pointer, CGF.VoidPtrTy); + result = CGF.Builder.CreateGEP(result, index, "add.ptr"); + return CGF.Builder.CreateBitCast(result, pointer->getType()); + } + + if (CGF.getLangOpts().isSignedOverflowDefined()) + return CGF.Builder.CreateGEP(pointer, index, "add.ptr"); + + return CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction, + op.E->getExprLoc(), "add.ptr"); +} + +// Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and +// Addend. Use negMul and negAdd to negate the first operand of the Mul or +// the add operand respectively. This allows fmuladd to represent a*b-c, or +// c-a*b. Patterns in LLVM should catch the negated forms and translate them to +// efficient operations. +static Value* buildFMulAdd(llvm::BinaryOperator *MulOp, Value *Addend, + const CodeGenFunction &CGF, CGBuilderTy &Builder, + bool negMul, bool negAdd) { + assert(!(negMul && negAdd) && "Only one of negMul and negAdd should be set."); + + Value *MulOp0 = MulOp->getOperand(0); + Value *MulOp1 = MulOp->getOperand(1); + if (negMul) { + MulOp0 = + Builder.CreateFSub( + llvm::ConstantFP::getZeroValueForNegation(MulOp0->getType()), MulOp0, + "neg"); + } else if (negAdd) { + Addend = + Builder.CreateFSub( + llvm::ConstantFP::getZeroValueForNegation(Addend->getType()), Addend, + "neg"); + } + + Value *FMulAdd = Builder.CreateCall( + CGF.CGM.getIntrinsic(llvm::Intrinsic::fmuladd, Addend->getType()), + {MulOp0, MulOp1, Addend}); + MulOp->eraseFromParent(); + + return FMulAdd; +} + +// Check whether it would be legal to emit an fmuladd intrinsic call to +// represent op and if so, build the fmuladd. +// +// Checks that (a) the operation is fusable, and (b) -ffp-contract=on. +// Does NOT check the type of the operation - it's assumed that this function +// will be called from contexts where it's known that the type is contractable. +static Value* tryEmitFMulAdd(const BinOpInfo &op, + const CodeGenFunction &CGF, CGBuilderTy &Builder, + bool isSub=false) { + + assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign || + op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) && + "Only fadd/fsub can be the root of an fmuladd."); + + // Check whether this op is marked as fusable. + if (!op.FPFeatures.allowFPContractWithinStatement()) + return nullptr; + + // We have a potentially fusable op. Look for a mul on one of the operands. + // Also, make sure that the mul result isn't used directly. In that case, + // there's no point creating a muladd operation. + if (auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) { + if (LHSBinOp->getOpcode() == llvm::Instruction::FMul && + LHSBinOp->use_empty()) + return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, false, isSub); + } + if (auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) { + if (RHSBinOp->getOpcode() == llvm::Instruction::FMul && + RHSBinOp->use_empty()) + return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub, false); + } + + return nullptr; +} + +Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) { + if (op.LHS->getType()->isPointerTy() || + op.RHS->getType()->isPointerTy()) + return emitPointerArithmetic(CGF, op, CodeGenFunction::NotSubtraction); + + if (op.Ty->isSignedIntegerOrEnumerationType()) { + switch (CGF.getLangOpts().getSignedOverflowBehavior()) { + case LangOptions::SOB_Defined: + return Builder.CreateAdd(op.LHS, op.RHS, "add"); + case LangOptions::SOB_Undefined: + if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) + return Builder.CreateNSWAdd(op.LHS, op.RHS, "add"); + LLVM_FALLTHROUGH; + case LangOptions::SOB_Trapping: + if (CanElideOverflowCheck(CGF.getContext(), op)) + return Builder.CreateNSWAdd(op.LHS, op.RHS, "add"); + return EmitOverflowCheckedBinOp(op); + } + } + + if (op.Ty->isUnsignedIntegerType() && + CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) && + !CanElideOverflowCheck(CGF.getContext(), op)) + return EmitOverflowCheckedBinOp(op); + + if (op.LHS->getType()->isFPOrFPVectorTy()) { + // Try to form an fmuladd. + if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder)) + return FMulAdd; + + Value *V = Builder.CreateFAdd(op.LHS, op.RHS, "add"); + return propagateFMFlags(V, op); + } + + if (op.isFixedPointBinOp()) + return EmitFixedPointBinOp(op); + + return Builder.CreateAdd(op.LHS, op.RHS, "add"); +} + +/// The resulting value must be calculated with exact precision, so the operands +/// may not be the same type. +Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) { + using llvm::APSInt; + using llvm::ConstantInt; + + const auto *BinOp = cast<BinaryOperator>(op.E); + + // The result is a fixed point type and at least one of the operands is fixed + // point while the other is either fixed point or an int. This resulting type + // should be determined by Sema::handleFixedPointConversions(). + QualType ResultTy = op.Ty; + QualType LHSTy = BinOp->getLHS()->getType(); + QualType RHSTy = BinOp->getRHS()->getType(); + ASTContext &Ctx = CGF.getContext(); + Value *LHS = op.LHS; + Value *RHS = op.RHS; + + auto LHSFixedSema = Ctx.getFixedPointSemantics(LHSTy); + auto RHSFixedSema = Ctx.getFixedPointSemantics(RHSTy); + auto ResultFixedSema = Ctx.getFixedPointSemantics(ResultTy); + auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema); + + // Convert the operands to the full precision type. + Value *FullLHS = EmitFixedPointConversion(LHS, LHSFixedSema, CommonFixedSema, + BinOp->getExprLoc()); + Value *FullRHS = EmitFixedPointConversion(RHS, RHSFixedSema, CommonFixedSema, + BinOp->getExprLoc()); + + // Perform the actual addition. + Value *Result; + switch (BinOp->getOpcode()) { + case BO_Add: { + if (ResultFixedSema.isSaturated()) { + llvm::Intrinsic::ID IID = ResultFixedSema.isSigned() + ? llvm::Intrinsic::sadd_sat + : llvm::Intrinsic::uadd_sat; + Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS); + } else { + Result = Builder.CreateAdd(FullLHS, FullRHS); + } + break; + } + case BO_Sub: { + if (ResultFixedSema.isSaturated()) { + llvm::Intrinsic::ID IID = ResultFixedSema.isSigned() + ? llvm::Intrinsic::ssub_sat + : llvm::Intrinsic::usub_sat; + Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS); + } else { + Result = Builder.CreateSub(FullLHS, FullRHS); + } + break; + } + case BO_LT: + return CommonFixedSema.isSigned() ? Builder.CreateICmpSLT(FullLHS, FullRHS) + : Builder.CreateICmpULT(FullLHS, FullRHS); + case BO_GT: + return CommonFixedSema.isSigned() ? Builder.CreateICmpSGT(FullLHS, FullRHS) + : Builder.CreateICmpUGT(FullLHS, FullRHS); + case BO_LE: + return CommonFixedSema.isSigned() ? Builder.CreateICmpSLE(FullLHS, FullRHS) + : Builder.CreateICmpULE(FullLHS, FullRHS); + case BO_GE: + return CommonFixedSema.isSigned() ? Builder.CreateICmpSGE(FullLHS, FullRHS) + : Builder.CreateICmpUGE(FullLHS, FullRHS); + case BO_EQ: + // For equality operations, we assume any padding bits on unsigned types are + // zero'd out. They could be overwritten through non-saturating operations + // that cause overflow, but this leads to undefined behavior. + return Builder.CreateICmpEQ(FullLHS, FullRHS); + case BO_NE: + return Builder.CreateICmpNE(FullLHS, FullRHS); + case BO_Mul: + case BO_Div: + case BO_Shl: + case BO_Shr: + case BO_Cmp: + case BO_LAnd: + case BO_LOr: + case BO_MulAssign: + case BO_DivAssign: + case BO_AddAssign: + case BO_SubAssign: + case BO_ShlAssign: + case BO_ShrAssign: + llvm_unreachable("Found unimplemented fixed point binary operation"); + case BO_PtrMemD: + case BO_PtrMemI: + case BO_Rem: + case BO_Xor: + case BO_And: + case BO_Or: + case BO_Assign: + case BO_RemAssign: + case BO_AndAssign: + case BO_XorAssign: + case BO_OrAssign: + case BO_Comma: + llvm_unreachable("Found unsupported binary operation for fixed point types."); + } + + // Convert to the result type. + return EmitFixedPointConversion(Result, CommonFixedSema, ResultFixedSema, + BinOp->getExprLoc()); +} + +Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) { + // The LHS is always a pointer if either side is. + if (!op.LHS->getType()->isPointerTy()) { + if (op.Ty->isSignedIntegerOrEnumerationType()) { + switch (CGF.getLangOpts().getSignedOverflowBehavior()) { + case LangOptions::SOB_Defined: + return Builder.CreateSub(op.LHS, op.RHS, "sub"); + case LangOptions::SOB_Undefined: + if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) + return Builder.CreateNSWSub(op.LHS, op.RHS, "sub"); + LLVM_FALLTHROUGH; + case LangOptions::SOB_Trapping: + if (CanElideOverflowCheck(CGF.getContext(), op)) + return Builder.CreateNSWSub(op.LHS, op.RHS, "sub"); + return EmitOverflowCheckedBinOp(op); + } + } + + if (op.Ty->isUnsignedIntegerType() && + CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) && + !CanElideOverflowCheck(CGF.getContext(), op)) + return EmitOverflowCheckedBinOp(op); + + if (op.LHS->getType()->isFPOrFPVectorTy()) { + // Try to form an fmuladd. + if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true)) + return FMulAdd; + Value *V = Builder.CreateFSub(op.LHS, op.RHS, "sub"); + return propagateFMFlags(V, op); + } + + if (op.isFixedPointBinOp()) + return EmitFixedPointBinOp(op); + + return Builder.CreateSub(op.LHS, op.RHS, "sub"); + } + + // If the RHS is not a pointer, then we have normal pointer + // arithmetic. + if (!op.RHS->getType()->isPointerTy()) + return emitPointerArithmetic(CGF, op, CodeGenFunction::IsSubtraction); + + // Otherwise, this is a pointer subtraction. + + // Do the raw subtraction part. + llvm::Value *LHS + = Builder.CreatePtrToInt(op.LHS, CGF.PtrDiffTy, "sub.ptr.lhs.cast"); + llvm::Value *RHS + = Builder.CreatePtrToInt(op.RHS, CGF.PtrDiffTy, "sub.ptr.rhs.cast"); + Value *diffInChars = Builder.CreateSub(LHS, RHS, "sub.ptr.sub"); + + // Okay, figure out the element size. + const BinaryOperator *expr = cast<BinaryOperator>(op.E); + QualType elementType = expr->getLHS()->getType()->getPointeeType(); + + llvm::Value *divisor = nullptr; + + // For a variable-length array, this is going to be non-constant. + if (const VariableArrayType *vla + = CGF.getContext().getAsVariableArrayType(elementType)) { + auto VlaSize = CGF.getVLASize(vla); + elementType = VlaSize.Type; + divisor = VlaSize.NumElts; + + // Scale the number of non-VLA elements by the non-VLA element size. + CharUnits eltSize = CGF.getContext().getTypeSizeInChars(elementType); + if (!eltSize.isOne()) + divisor = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), divisor); + + // For everything elese, we can just compute it, safe in the + // assumption that Sema won't let anything through that we can't + // safely compute the size of. + } else { + CharUnits elementSize; + // Handle GCC extension for pointer arithmetic on void* and + // function pointer types. + if (elementType->isVoidType() || elementType->isFunctionType()) + elementSize = CharUnits::One(); + else + elementSize = CGF.getContext().getTypeSizeInChars(elementType); + + // Don't even emit the divide for element size of 1. + if (elementSize.isOne()) + return diffInChars; + + divisor = CGF.CGM.getSize(elementSize); + } + + // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since + // pointer difference in C is only defined in the case where both operands + // are pointing to elements of an array. + return Builder.CreateExactSDiv(diffInChars, divisor, "sub.ptr.div"); +} + +Value *ScalarExprEmitter::GetWidthMinusOneValue(Value* LHS,Value* RHS) { + llvm::IntegerType *Ty; + if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType())) + Ty = cast<llvm::IntegerType>(VT->getElementType()); + else + Ty = cast<llvm::IntegerType>(LHS->getType()); + return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1); +} + +Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { + // LLVM requires the LHS and RHS to be the same type: promote or truncate the + // RHS to the same size as the LHS. + Value *RHS = Ops.RHS; + if (Ops.LHS->getType() != RHS->getType()) + RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); + + bool SanitizeBase = CGF.SanOpts.has(SanitizerKind::ShiftBase) && + Ops.Ty->hasSignedIntegerRepresentation() && + !CGF.getLangOpts().isSignedOverflowDefined() && + !CGF.getLangOpts().CPlusPlus2a; + bool SanitizeExponent = CGF.SanOpts.has(SanitizerKind::ShiftExponent); + // OpenCL 6.3j: shift values are effectively % word size of LHS. + if (CGF.getLangOpts().OpenCL) + RHS = + Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shl.mask"); + else if ((SanitizeBase || SanitizeExponent) && + isa<llvm::IntegerType>(Ops.LHS->getType())) { + CodeGenFunction::SanitizerScope SanScope(&CGF); + SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks; + llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS); + llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne); + + if (SanitizeExponent) { + Checks.push_back( + std::make_pair(ValidExponent, SanitizerKind::ShiftExponent)); + } + + if (SanitizeBase) { + // Check whether we are shifting any non-zero bits off the top of the + // integer. We only emit this check if exponent is valid - otherwise + // instructions below will have undefined behavior themselves. + llvm::BasicBlock *Orig = Builder.GetInsertBlock(); + llvm::BasicBlock *Cont = CGF.createBasicBlock("cont"); + llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check"); + Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont); + llvm::Value *PromotedWidthMinusOne = + (RHS == Ops.RHS) ? WidthMinusOne + : GetWidthMinusOneValue(Ops.LHS, RHS); + CGF.EmitBlock(CheckShiftBase); + llvm::Value *BitsShiftedOff = Builder.CreateLShr( + Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros", + /*NUW*/ true, /*NSW*/ true), + "shl.check"); + if (CGF.getLangOpts().CPlusPlus) { + // In C99, we are not permitted to shift a 1 bit into the sign bit. + // Under C++11's rules, shifting a 1 bit into the sign bit is + // OK, but shifting a 1 bit out of it is not. (C89 and C++03 don't + // define signed left shifts, so we use the C99 and C++11 rules there). + llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1); + BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One); + } + llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0); + llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero); + CGF.EmitBlock(Cont); + llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2); + BaseCheck->addIncoming(Builder.getTrue(), Orig); + BaseCheck->addIncoming(ValidBase, CheckShiftBase); + Checks.push_back(std::make_pair(BaseCheck, SanitizerKind::ShiftBase)); + } + + assert(!Checks.empty()); + EmitBinOpCheck(Checks, Ops); + } + + return Builder.CreateShl(Ops.LHS, RHS, "shl"); +} + +Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) { + // LLVM requires the LHS and RHS to be the same type: promote or truncate the + // RHS to the same size as the LHS. + Value *RHS = Ops.RHS; + if (Ops.LHS->getType() != RHS->getType()) + RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); + + // OpenCL 6.3j: shift values are effectively % word size of LHS. + if (CGF.getLangOpts().OpenCL) + RHS = + Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shr.mask"); + else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) && + isa<llvm::IntegerType>(Ops.LHS->getType())) { + CodeGenFunction::SanitizerScope SanScope(&CGF); + llvm::Value *Valid = + Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS)); + EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops); + } + + if (Ops.Ty->hasUnsignedIntegerRepresentation()) + return Builder.CreateLShr(Ops.LHS, RHS, "shr"); + return Builder.CreateAShr(Ops.LHS, RHS, "shr"); +} + +enum IntrinsicType { VCMPEQ, VCMPGT }; +// return corresponding comparison intrinsic for given vector type +static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, + BuiltinType::Kind ElemKind) { + switch (ElemKind) { + default: llvm_unreachable("unexpected element type"); + case BuiltinType::Char_U: + case BuiltinType::UChar: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p : + llvm::Intrinsic::ppc_altivec_vcmpgtub_p; + case BuiltinType::Char_S: + case BuiltinType::SChar: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p : + llvm::Intrinsic::ppc_altivec_vcmpgtsb_p; + case BuiltinType::UShort: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p : + llvm::Intrinsic::ppc_altivec_vcmpgtuh_p; + case BuiltinType::Short: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p : + llvm::Intrinsic::ppc_altivec_vcmpgtsh_p; + case BuiltinType::UInt: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p : + llvm::Intrinsic::ppc_altivec_vcmpgtuw_p; + case BuiltinType::Int: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p : + llvm::Intrinsic::ppc_altivec_vcmpgtsw_p; + case BuiltinType::ULong: + case BuiltinType::ULongLong: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p : + llvm::Intrinsic::ppc_altivec_vcmpgtud_p; + case BuiltinType::Long: + case BuiltinType::LongLong: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p : + llvm::Intrinsic::ppc_altivec_vcmpgtsd_p; + case BuiltinType::Float: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p : + llvm::Intrinsic::ppc_altivec_vcmpgtfp_p; + case BuiltinType::Double: + return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p : + llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p; + } +} + +Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E, + llvm::CmpInst::Predicate UICmpOpc, + llvm::CmpInst::Predicate SICmpOpc, + llvm::CmpInst::Predicate FCmpOpc) { + TestAndClearIgnoreResultAssign(); + Value *Result; + QualType LHSTy = E->getLHS()->getType(); + QualType RHSTy = E->getRHS()->getType(); + if (const MemberPointerType *MPT = LHSTy->getAs<MemberPointerType>()) { + assert(E->getOpcode() == BO_EQ || + E->getOpcode() == BO_NE); + Value *LHS = CGF.EmitScalarExpr(E->getLHS()); + Value *RHS = CGF.EmitScalarExpr(E->getRHS()); + Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison( + CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE); + } else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) { + BinOpInfo BOInfo = EmitBinOps(E); + Value *LHS = BOInfo.LHS; + Value *RHS = BOInfo.RHS; + + // If AltiVec, the comparison results in a numeric type, so we use + // intrinsics comparing vectors and giving 0 or 1 as a result + if (LHSTy->isVectorType() && !E->getType()->isVectorType()) { + // constants for mapping CR6 register bits to predicate result + enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6; + + llvm::Intrinsic::ID ID = llvm::Intrinsic::not_intrinsic; + + // in several cases vector arguments order will be reversed + Value *FirstVecArg = LHS, + *SecondVecArg = RHS; + + QualType ElTy = LHSTy->castAs<VectorType>()->getElementType(); + const BuiltinType *BTy = ElTy->getAs<BuiltinType>(); + BuiltinType::Kind ElementKind = BTy->getKind(); + + switch(E->getOpcode()) { + default: llvm_unreachable("is not a comparison operation"); + case BO_EQ: + CR6 = CR6_LT; + ID = GetIntrinsic(VCMPEQ, ElementKind); + break; + case BO_NE: + CR6 = CR6_EQ; + ID = GetIntrinsic(VCMPEQ, ElementKind); + break; + case BO_LT: + CR6 = CR6_LT; + ID = GetIntrinsic(VCMPGT, ElementKind); + std::swap(FirstVecArg, SecondVecArg); + break; + case BO_GT: + CR6 = CR6_LT; + ID = GetIntrinsic(VCMPGT, ElementKind); + break; + case BO_LE: + if (ElementKind == BuiltinType::Float) { + CR6 = CR6_LT; + ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p; + std::swap(FirstVecArg, SecondVecArg); + } + else { + CR6 = CR6_EQ; + ID = GetIntrinsic(VCMPGT, ElementKind); + } + break; + case BO_GE: + if (ElementKind == BuiltinType::Float) { + CR6 = CR6_LT; + ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p; + } + else { + CR6 = CR6_EQ; + ID = GetIntrinsic(VCMPGT, ElementKind); + std::swap(FirstVecArg, SecondVecArg); + } + break; + } + + Value *CR6Param = Builder.getInt32(CR6); + llvm::Function *F = CGF.CGM.getIntrinsic(ID); + Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg}); + + // The result type of intrinsic may not be same as E->getType(). + // If E->getType() is not BoolTy, EmitScalarConversion will do the + // conversion work. If E->getType() is BoolTy, EmitScalarConversion will + // do nothing, if ResultTy is not i1 at the same time, it will cause + // crash later. + llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType()); + if (ResultTy->getBitWidth() > 1 && + E->getType() == CGF.getContext().BoolTy) + Result = Builder.CreateTrunc(Result, Builder.getInt1Ty()); + return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(), + E->getExprLoc()); + } + + if (BOInfo.isFixedPointBinOp()) { + Result = EmitFixedPointBinOp(BOInfo); + } else if (LHS->getType()->isFPOrFPVectorTy()) { + Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp"); + } else if (LHSTy->hasSignedIntegerRepresentation()) { + Result = Builder.CreateICmp(SICmpOpc, LHS, RHS, "cmp"); + } else { + // Unsigned integers and pointers. + + if (CGF.CGM.getCodeGenOpts().StrictVTablePointers && + !isa<llvm::ConstantPointerNull>(LHS) && + !isa<llvm::ConstantPointerNull>(RHS)) { + + // Dynamic information is required to be stripped for comparisons, + // because it could leak the dynamic information. Based on comparisons + // of pointers to dynamic objects, the optimizer can replace one pointer + // with another, which might be incorrect in presence of invariant + // groups. Comparison with null is safe because null does not carry any + // dynamic information. + if (LHSTy.mayBeDynamicClass()) + LHS = Builder.CreateStripInvariantGroup(LHS); + if (RHSTy.mayBeDynamicClass()) + RHS = Builder.CreateStripInvariantGroup(RHS); + } + + Result = Builder.CreateICmp(UICmpOpc, LHS, RHS, "cmp"); + } + + // If this is a vector comparison, sign extend the result to the appropriate + // vector integer type and return it (don't convert to bool). + if (LHSTy->isVectorType()) + return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext"); + + } else { + // Complex Comparison: can only be an equality comparison. + CodeGenFunction::ComplexPairTy LHS, RHS; + QualType CETy; + if (auto *CTy = LHSTy->getAs<ComplexType>()) { + LHS = CGF.EmitComplexExpr(E->getLHS()); + CETy = CTy->getElementType(); + } else { + LHS.first = Visit(E->getLHS()); + LHS.second = llvm::Constant::getNullValue(LHS.first->getType()); + CETy = LHSTy; + } + if (auto *CTy = RHSTy->getAs<ComplexType>()) { + RHS = CGF.EmitComplexExpr(E->getRHS()); + assert(CGF.getContext().hasSameUnqualifiedType(CETy, + CTy->getElementType()) && + "The element types must always match."); + (void)CTy; + } else { + RHS.first = Visit(E->getRHS()); + RHS.second = llvm::Constant::getNullValue(RHS.first->getType()); + assert(CGF.getContext().hasSameUnqualifiedType(CETy, RHSTy) && + "The element types must always match."); + } + + Value *ResultR, *ResultI; + if (CETy->isRealFloatingType()) { + ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first, "cmp.r"); + ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second, "cmp.i"); + } else { + // Complex comparisons can only be equality comparisons. As such, signed + // and unsigned opcodes are the same. + ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first, "cmp.r"); + ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second, "cmp.i"); + } + + if (E->getOpcode() == BO_EQ) { + Result = Builder.CreateAnd(ResultR, ResultI, "and.ri"); + } else { + assert(E->getOpcode() == BO_NE && + "Complex comparison other than == or != ?"); + Result = Builder.CreateOr(ResultR, ResultI, "or.ri"); + } + } + + return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(), + E->getExprLoc()); +} + +Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { + bool Ignore = TestAndClearIgnoreResultAssign(); + + Value *RHS; + LValue LHS; + + switch (E->getLHS()->getType().getObjCLifetime()) { + case Qualifiers::OCL_Strong: + std::tie(LHS, RHS) = CGF.EmitARCStoreStrong(E, Ignore); + break; + + case Qualifiers::OCL_Autoreleasing: + std::tie(LHS, RHS) = CGF.EmitARCStoreAutoreleasing(E); + break; + + case Qualifiers::OCL_ExplicitNone: + std::tie(LHS, RHS) = CGF.EmitARCStoreUnsafeUnretained(E, Ignore); + break; + + case Qualifiers::OCL_Weak: + RHS = Visit(E->getRHS()); + LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store); + RHS = CGF.EmitARCStoreWeak(LHS.getAddress(), RHS, Ignore); + break; + + case Qualifiers::OCL_None: + // __block variables need to have the rhs evaluated first, plus + // this should improve codegen just a little. + RHS = Visit(E->getRHS()); + LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store); + + // Store the value into the LHS. Bit-fields are handled specially + // because the result is altered by the store, i.e., [C99 6.5.16p1] + // 'An assignment expression has the value of the left operand after + // the assignment...'. + if (LHS.isBitField()) { + CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS); + } else { + CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc()); + CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS); + } + } + + // If the result is clearly ignored, return now. + if (Ignore) + return nullptr; + + // The result of an assignment in C is the assigned r-value. + if (!CGF.getLangOpts().CPlusPlus) + return RHS; + + // If the lvalue is non-volatile, return the computed value of the assignment. + if (!LHS.isVolatileQualified()) + return RHS; + + // Otherwise, reload the value. + return EmitLoadOfLValue(LHS, E->getExprLoc()); +} + +Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { + // Perform vector logical and on comparisons with zero vectors. + if (E->getType()->isVectorType()) { + CGF.incrementProfileCounter(E); + + Value *LHS = Visit(E->getLHS()); + Value *RHS = Visit(E->getRHS()); + Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); + if (LHS->getType()->isFPOrFPVectorTy()) { + LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); + RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); + } else { + LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp"); + RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp"); + } + Value *And = Builder.CreateAnd(LHS, RHS); + return Builder.CreateSExt(And, ConvertType(E->getType()), "sext"); + } + + llvm::Type *ResTy = ConvertType(E->getType()); + + // If we have 0 && RHS, see if we can elide RHS, if so, just return 0. + // If we have 1 && X, just emit X without inserting the control flow. + bool LHSCondVal; + if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) { + if (LHSCondVal) { // If we have 1 && X, just emit X. + CGF.incrementProfileCounter(E); + + Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); + // ZExt result to int or bool. + return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext"); + } + + // 0 && RHS: If it is safe, just elide the RHS, and return 0/false. + if (!CGF.ContainsLabel(E->getRHS())) + return llvm::Constant::getNullValue(ResTy); + } + + llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end"); + llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("land.rhs"); + + CodeGenFunction::ConditionalEvaluation eval(CGF); + + // Branch on the LHS first. If it is false, go to the failure (cont) block. + CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock, + CGF.getProfileCount(E->getRHS())); + + // Any edges into the ContBlock are now from an (indeterminate number of) + // edges from this first condition. All of these values will be false. Start + // setting up the PHI node in the Cont Block for this. + llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2, + "", ContBlock); + for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock); + PI != PE; ++PI) + PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI); + + eval.begin(CGF); + CGF.EmitBlock(RHSBlock); + CGF.incrementProfileCounter(E); + Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); + eval.end(CGF); + + // Reaquire the RHS block, as there may be subblocks inserted. + RHSBlock = Builder.GetInsertBlock(); + + // Emit an unconditional branch from this block to ContBlock. + { + // There is no need to emit line number for unconditional branch. + auto NL = ApplyDebugLocation::CreateEmpty(CGF); + CGF.EmitBlock(ContBlock); + } + // Insert an entry into the phi node for the edge with the value of RHSCond. + PN->addIncoming(RHSCond, RHSBlock); + + // Artificial location to preserve the scope information + { + auto NL = ApplyDebugLocation::CreateArtificial(CGF); + PN->setDebugLoc(Builder.getCurrentDebugLocation()); + } + + // ZExt result to int. + return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext"); +} + +Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { + // Perform vector logical or on comparisons with zero vectors. + if (E->getType()->isVectorType()) { + CGF.incrementProfileCounter(E); + + Value *LHS = Visit(E->getLHS()); + Value *RHS = Visit(E->getRHS()); + Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); + if (LHS->getType()->isFPOrFPVectorTy()) { + LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); + RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); + } else { + LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp"); + RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp"); + } + Value *Or = Builder.CreateOr(LHS, RHS); + return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext"); + } + + llvm::Type *ResTy = ConvertType(E->getType()); + + // If we have 1 || RHS, see if we can elide RHS, if so, just return 1. + // If we have 0 || X, just emit X without inserting the control flow. + bool LHSCondVal; + if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) { + if (!LHSCondVal) { // If we have 0 || X, just emit X. + CGF.incrementProfileCounter(E); + + Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); + // ZExt result to int or bool. + return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext"); + } + + // 1 || RHS: If it is safe, just elide the RHS, and return 1/true. + if (!CGF.ContainsLabel(E->getRHS())) + return llvm::ConstantInt::get(ResTy, 1); + } + + llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end"); + llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs"); + + CodeGenFunction::ConditionalEvaluation eval(CGF); + + // Branch on the LHS first. If it is true, go to the success (cont) block. + CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock, + CGF.getCurrentProfileCount() - + CGF.getProfileCount(E->getRHS())); + + // Any edges into the ContBlock are now from an (indeterminate number of) + // edges from this first condition. All of these values will be true. Start + // setting up the PHI node in the Cont Block for this. + llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2, + "", ContBlock); + for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock); + PI != PE; ++PI) + PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI); + + eval.begin(CGF); + + // Emit the RHS condition as a bool value. + CGF.EmitBlock(RHSBlock); + CGF.incrementProfileCounter(E); + Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); + + eval.end(CGF); + + // Reaquire the RHS block, as there may be subblocks inserted. + RHSBlock = Builder.GetInsertBlock(); + + // Emit an unconditional branch from this block to ContBlock. Insert an entry + // into the phi node for the edge with the value of RHSCond. + CGF.EmitBlock(ContBlock); + PN->addIncoming(RHSCond, RHSBlock); + + // ZExt result to int. + return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext"); +} + +Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) { + CGF.EmitIgnoredExpr(E->getLHS()); + CGF.EnsureInsertPoint(); + return Visit(E->getRHS()); +} + +//===----------------------------------------------------------------------===// +// Other Operators +//===----------------------------------------------------------------------===// + +/// isCheapEnoughToEvaluateUnconditionally - Return true if the specified +/// expression is cheap enough and side-effect-free enough to evaluate +/// unconditionally instead of conditionally. This is used to convert control +/// flow into selects in some cases. +static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, + CodeGenFunction &CGF) { + // Anything that is an integer or floating point constant is fine. + return E->IgnoreParens()->isEvaluatable(CGF.getContext()); + + // Even non-volatile automatic variables can't be evaluated unconditionally. + // Referencing a thread_local may cause non-trivial initialization work to + // occur. If we're inside a lambda and one of the variables is from the scope + // outside the lambda, that function may have returned already. Reading its + // locals is a bad idea. Also, these reads may introduce races there didn't + // exist in the source-level program. +} + + +Value *ScalarExprEmitter:: +VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { + TestAndClearIgnoreResultAssign(); + + // Bind the common expression if necessary. + CodeGenFunction::OpaqueValueMapping binding(CGF, E); + + Expr *condExpr = E->getCond(); + Expr *lhsExpr = E->getTrueExpr(); + Expr *rhsExpr = E->getFalseExpr(); + + // If the condition constant folds and can be elided, try to avoid emitting + // the condition and the dead arm. + bool CondExprBool; + if (CGF.ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) { + Expr *live = lhsExpr, *dead = rhsExpr; + if (!CondExprBool) std::swap(live, dead); + + // If the dead side doesn't have labels we need, just emit the Live part. + if (!CGF.ContainsLabel(dead)) { + if (CondExprBool) + CGF.incrementProfileCounter(E); + Value *Result = Visit(live); + + // If the live part is a throw expression, it acts like it has a void + // type, so evaluating it returns a null Value*. However, a conditional + // with non-void type must return a non-null Value*. + if (!Result && !E->getType()->isVoidType()) + Result = llvm::UndefValue::get(CGF.ConvertType(E->getType())); + + return Result; + } + } + + // OpenCL: If the condition is a vector, we can treat this condition like + // the select function. + if (CGF.getLangOpts().OpenCL + && condExpr->getType()->isVectorType()) { + CGF.incrementProfileCounter(E); + + llvm::Value *CondV = CGF.EmitScalarExpr(condExpr); + llvm::Value *LHS = Visit(lhsExpr); + llvm::Value *RHS = Visit(rhsExpr); + + llvm::Type *condType = ConvertType(condExpr->getType()); + llvm::VectorType *vecTy = cast<llvm::VectorType>(condType); + + unsigned numElem = vecTy->getNumElements(); + llvm::Type *elemType = vecTy->getElementType(); + + llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy); + llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec); + llvm::Value *tmp = Builder.CreateSExt(TestMSB, + llvm::VectorType::get(elemType, + numElem), + "sext"); + llvm::Value *tmp2 = Builder.CreateNot(tmp); + + // Cast float to int to perform ANDs if necessary. + llvm::Value *RHSTmp = RHS; + llvm::Value *LHSTmp = LHS; + bool wasCast = false; + llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType()); + if (rhsVTy->getElementType()->isFloatingPointTy()) { + RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType()); + LHSTmp = Builder.CreateBitCast(LHS, tmp->getType()); + wasCast = true; + } + + llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2); + llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp); + llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4, "cond"); + if (wasCast) + tmp5 = Builder.CreateBitCast(tmp5, RHS->getType()); + + return tmp5; + } + + // If this is a really simple expression (like x ? 4 : 5), emit this as a + // select instead of as control flow. We can only do this if it is cheap and + // safe to evaluate the LHS and RHS unconditionally. + if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) && + isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) { + llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr); + llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty); + + CGF.incrementProfileCounter(E, StepV); + + llvm::Value *LHS = Visit(lhsExpr); + llvm::Value *RHS = Visit(rhsExpr); + if (!LHS) { + // If the conditional has void type, make sure we return a null Value*. + assert(!RHS && "LHS and RHS types must match"); + return nullptr; + } + return Builder.CreateSelect(CondV, LHS, RHS, "cond"); + } + + llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); + llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); + llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); + + CodeGenFunction::ConditionalEvaluation eval(CGF); + CGF.EmitBranchOnBoolExpr(condExpr, LHSBlock, RHSBlock, + CGF.getProfileCount(lhsExpr)); + + CGF.EmitBlock(LHSBlock); + CGF.incrementProfileCounter(E); + eval.begin(CGF); + Value *LHS = Visit(lhsExpr); + eval.end(CGF); + + LHSBlock = Builder.GetInsertBlock(); + Builder.CreateBr(ContBlock); + + CGF.EmitBlock(RHSBlock); + eval.begin(CGF); + Value *RHS = Visit(rhsExpr); + eval.end(CGF); + + RHSBlock = Builder.GetInsertBlock(); + CGF.EmitBlock(ContBlock); + + // If the LHS or RHS is a throw expression, it will be legitimately null. + if (!LHS) + return RHS; + if (!RHS) + return LHS; + + // Create a PHI node for the real part. + llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2, "cond"); + PN->addIncoming(LHS, LHSBlock); + PN->addIncoming(RHS, RHSBlock); + return PN; +} + +Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) { + return Visit(E->getChosenSubExpr()); +} + +Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { + QualType Ty = VE->getType(); + + if (Ty->isVariablyModifiedType()) + CGF.EmitVariablyModifiedType(Ty); + + Address ArgValue = Address::invalid(); + Address ArgPtr = CGF.EmitVAArg(VE, ArgValue); + + llvm::Type *ArgTy = ConvertType(VE->getType()); + + // If EmitVAArg fails, emit an error. + if (!ArgPtr.isValid()) { + CGF.ErrorUnsupported(VE, "va_arg expression"); + return llvm::UndefValue::get(ArgTy); + } + + // FIXME Volatility. + llvm::Value *Val = Builder.CreateLoad(ArgPtr); + + // If EmitVAArg promoted the type, we must truncate it. + if (ArgTy != Val->getType()) { + if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy()) + Val = Builder.CreateIntToPtr(Val, ArgTy); + else + Val = Builder.CreateTrunc(Val, ArgTy); + } + + return Val; +} + +Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) { + return CGF.EmitBlockLiteral(block); +} + +// Convert a vec3 to vec4, or vice versa. +static Value *ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, + Value *Src, unsigned NumElementsDst) { + llvm::Value *UnV = llvm::UndefValue::get(Src->getType()); + SmallVector<llvm::Constant*, 4> Args; + Args.push_back(Builder.getInt32(0)); + Args.push_back(Builder.getInt32(1)); + Args.push_back(Builder.getInt32(2)); + if (NumElementsDst == 4) + Args.push_back(llvm::UndefValue::get(CGF.Int32Ty)); + llvm::Constant *Mask = llvm::ConstantVector::get(Args); + return Builder.CreateShuffleVector(Src, UnV, Mask); +} + +// Create cast instructions for converting LLVM value \p Src to LLVM type \p +// DstTy. \p Src has the same size as \p DstTy. Both are single value types +// but could be scalar or vectors of different lengths, and either can be +// pointer. +// There are 4 cases: +// 1. non-pointer -> non-pointer : needs 1 bitcast +// 2. pointer -> pointer : needs 1 bitcast or addrspacecast +// 3. pointer -> non-pointer +// a) pointer -> intptr_t : needs 1 ptrtoint +// b) pointer -> non-intptr_t : needs 1 ptrtoint then 1 bitcast +// 4. non-pointer -> pointer +// a) intptr_t -> pointer : needs 1 inttoptr +// b) non-intptr_t -> pointer : needs 1 bitcast then 1 inttoptr +// Note: for cases 3b and 4b two casts are required since LLVM casts do not +// allow casting directly between pointer types and non-integer non-pointer +// types. +static Value *createCastsForTypeOfSameSize(CGBuilderTy &Builder, + const llvm::DataLayout &DL, + Value *Src, llvm::Type *DstTy, + StringRef Name = "") { + auto SrcTy = Src->getType(); + + // Case 1. + if (!SrcTy->isPointerTy() && !DstTy->isPointerTy()) + return Builder.CreateBitCast(Src, DstTy, Name); + + // Case 2. + if (SrcTy->isPointerTy() && DstTy->isPointerTy()) + return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name); + + // Case 3. + if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) { + // Case 3b. + if (!DstTy->isIntegerTy()) + Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy)); + // Cases 3a and 3b. + return Builder.CreateBitOrPointerCast(Src, DstTy, Name); + } + + // Case 4b. + if (!SrcTy->isIntegerTy()) + Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy)); + // Cases 4a and 4b. + return Builder.CreateIntToPtr(Src, DstTy, Name); +} + +Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) { + Value *Src = CGF.EmitScalarExpr(E->getSrcExpr()); + llvm::Type *DstTy = ConvertType(E->getType()); + + llvm::Type *SrcTy = Src->getType(); + unsigned NumElementsSrc = isa<llvm::VectorType>(SrcTy) ? + cast<llvm::VectorType>(SrcTy)->getNumElements() : 0; + unsigned NumElementsDst = isa<llvm::VectorType>(DstTy) ? + cast<llvm::VectorType>(DstTy)->getNumElements() : 0; + + // Going from vec3 to non-vec3 is a special case and requires a shuffle + // vector to get a vec4, then a bitcast if the target type is different. + if (NumElementsSrc == 3 && NumElementsDst != 3) { + Src = ConvertVec3AndVec4(Builder, CGF, Src, 4); + + if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) { + Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src, + DstTy); + } + + Src->setName("astype"); + return Src; + } + + // Going from non-vec3 to vec3 is a special case and requires a bitcast + // to vec4 if the original type is not vec4, then a shuffle vector to + // get a vec3. + if (NumElementsSrc != 3 && NumElementsDst == 3) { + if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) { + auto Vec4Ty = llvm::VectorType::get(DstTy->getVectorElementType(), 4); + Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src, + Vec4Ty); + } + + Src = ConvertVec3AndVec4(Builder, CGF, Src, 3); + Src->setName("astype"); + return Src; + } + + return createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), + Src, DstTy, "astype"); +} + +Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) { + return CGF.EmitAtomicExpr(E).getScalarVal(); +} + +//===----------------------------------------------------------------------===// +// Entry Point into this File +//===----------------------------------------------------------------------===// + +/// Emit the computation of the specified expression of scalar type, ignoring +/// the result. +Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) { + assert(E && hasScalarEvaluationKind(E->getType()) && + "Invalid scalar expression to emit"); + + return ScalarExprEmitter(*this, IgnoreResultAssign) + .Visit(const_cast<Expr *>(E)); +} + +/// Emit a conversion from the specified type to the specified destination type, +/// both of which are LLVM scalar types. +Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy, + QualType DstTy, + SourceLocation Loc) { + assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) && + "Invalid scalar expression to emit"); + return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc); +} + +/// Emit a conversion from the specified complex type to the specified +/// destination type, where the destination type is an LLVM scalar type. +Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src, + QualType SrcTy, + QualType DstTy, + SourceLocation Loc) { + assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) && + "Invalid complex -> scalar conversion"); + return ScalarExprEmitter(*this) + .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc); +} + + +llvm::Value *CodeGenFunction:: +EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, + bool isInc, bool isPre) { + return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre); +} + +LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) { + // object->isa or (*object).isa + // Generate code as for: *(Class*)object + + Expr *BaseExpr = E->getBase(); + Address Addr = Address::invalid(); + if (BaseExpr->isRValue()) { + Addr = Address(EmitScalarExpr(BaseExpr), getPointerAlign()); + } else { + Addr = EmitLValue(BaseExpr).getAddress(); + } + + // Cast the address to Class*. + Addr = Builder.CreateElementBitCast(Addr, ConvertType(E->getType())); + return MakeAddrLValue(Addr, E->getType()); +} + + +LValue CodeGenFunction::EmitCompoundAssignmentLValue( + const CompoundAssignOperator *E) { + ScalarExprEmitter Scalar(*this); + Value *Result = nullptr; + switch (E->getOpcode()) { +#define COMPOUND_OP(Op) \ + case BO_##Op##Assign: \ + return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \ + Result) + COMPOUND_OP(Mul); + COMPOUND_OP(Div); + COMPOUND_OP(Rem); + COMPOUND_OP(Add); + COMPOUND_OP(Sub); + COMPOUND_OP(Shl); + COMPOUND_OP(Shr); + COMPOUND_OP(And); + COMPOUND_OP(Xor); + COMPOUND_OP(Or); +#undef COMPOUND_OP + + case BO_PtrMemD: + case BO_PtrMemI: + case BO_Mul: + case BO_Div: + case BO_Rem: + case BO_Add: + case BO_Sub: + case BO_Shl: + case BO_Shr: + case BO_LT: + case BO_GT: + case BO_LE: + case BO_GE: + case BO_EQ: + case BO_NE: + case BO_Cmp: + case BO_And: + case BO_Xor: + case BO_Or: + case BO_LAnd: + case BO_LOr: + case BO_Assign: + case BO_Comma: + llvm_unreachable("Not valid compound assignment operators"); + } + + llvm_unreachable("Unhandled compound assignment operator"); +} + +struct GEPOffsetAndOverflow { + // The total (signed) byte offset for the GEP. + llvm::Value *TotalOffset; + // The offset overflow flag - true if the total offset overflows. + llvm::Value *OffsetOverflows; +}; + +/// Evaluate given GEPVal, which is either an inbounds GEP, or a constant, +/// and compute the total offset it applies from it's base pointer BasePtr. +/// Returns offset in bytes and a boolean flag whether an overflow happened +/// during evaluation. +static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, + llvm::LLVMContext &VMContext, + CodeGenModule &CGM, + CGBuilderTy Builder) { + const auto &DL = CGM.getDataLayout(); + + // The total (signed) byte offset for the GEP. + llvm::Value *TotalOffset = nullptr; + + // Was the GEP already reduced to a constant? + if (isa<llvm::Constant>(GEPVal)) { + // Compute the offset by casting both pointers to integers and subtracting: + // GEPVal = BasePtr + ptr(Offset) <--> Offset = int(GEPVal) - int(BasePtr) + Value *BasePtr_int = + Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->getType())); + Value *GEPVal_int = + Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->getType())); + TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int); + return {TotalOffset, /*OffsetOverflows=*/Builder.getFalse()}; + } + + auto *GEP = cast<llvm::GEPOperator>(GEPVal); + assert(GEP->getPointerOperand() == BasePtr && + "BasePtr must be the the base of the GEP."); + assert(GEP->isInBounds() && "Expected inbounds GEP"); + + auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType()); + + // Grab references to the signed add/mul overflow intrinsics for intptr_t. + auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy); + auto *SAddIntrinsic = + CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy); + auto *SMulIntrinsic = + CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy); + + // The offset overflow flag - true if the total offset overflows. + llvm::Value *OffsetOverflows = Builder.getFalse(); + + /// Return the result of the given binary operation. + auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS, + llvm::Value *RHS) -> llvm::Value * { + assert((Opcode == BO_Add || Opcode == BO_Mul) && "Can't eval binop"); + + // If the operands are constants, return a constant result. + if (auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) { + if (auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) { + llvm::APInt N; + bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode, + /*Signed=*/true, N); + if (HasOverflow) + OffsetOverflows = Builder.getTrue(); + return llvm::ConstantInt::get(VMContext, N); + } + } + + // Otherwise, compute the result with checked arithmetic. + auto *ResultAndOverflow = Builder.CreateCall( + (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS}); + OffsetOverflows = Builder.CreateOr( + Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows); + return Builder.CreateExtractValue(ResultAndOverflow, 0); + }; + + // Determine the total byte offset by looking at each GEP operand. + for (auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP); + GTI != GTE; ++GTI) { + llvm::Value *LocalOffset; + auto *Index = GTI.getOperand(); + // Compute the local offset contributed by this indexing step: + if (auto *STy = GTI.getStructTypeOrNull()) { + // For struct indexing, the local offset is the byte position of the + // specified field. + unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue(); + LocalOffset = llvm::ConstantInt::get( + IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo)); + } else { + // Otherwise this is array-like indexing. The local offset is the index + // multiplied by the element size. + auto *ElementSize = llvm::ConstantInt::get( + IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType())); + auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true); + LocalOffset = eval(BO_Mul, ElementSize, IndexS); + } + + // If this is the first offset, set it as the total offset. Otherwise, add + // the local offset into the running total. + if (!TotalOffset || TotalOffset == Zero) + TotalOffset = LocalOffset; + else + TotalOffset = eval(BO_Add, TotalOffset, LocalOffset); + } + + return {TotalOffset, OffsetOverflows}; +} + +Value * +CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList, + bool SignedIndices, bool IsSubtraction, + SourceLocation Loc, const Twine &Name) { + Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name); + + // If the pointer overflow sanitizer isn't enabled, do nothing. + if (!SanOpts.has(SanitizerKind::PointerOverflow)) + return GEPVal; + + llvm::Type *PtrTy = Ptr->getType(); + + // Perform nullptr-and-offset check unless the nullptr is defined. + bool PerformNullCheck = !NullPointerIsDefined( + Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace()); + // Check for overflows unless the GEP got constant-folded, + // and only in the default address space + bool PerformOverflowCheck = + !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0; + + if (!(PerformNullCheck || PerformOverflowCheck)) + return GEPVal; + + const auto &DL = CGM.getDataLayout(); + + SanitizerScope SanScope(this); + llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy); + + GEPOffsetAndOverflow EvaluatedGEP = + EmitGEPOffsetInBytes(Ptr, GEPVal, getLLVMContext(), CGM, Builder); + + assert((!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) || + EvaluatedGEP.OffsetOverflows == Builder.getFalse()) && + "If the offset got constant-folded, we don't expect that there was an " + "overflow."); + + auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy); + + // Common case: if the total offset is zero, and we are using C++ semantics, + // where nullptr+0 is defined, don't emit a check. + if (EvaluatedGEP.TotalOffset == Zero && CGM.getLangOpts().CPlusPlus) + return GEPVal; + + // Now that we've computed the total offset, add it to the base pointer (with + // wrapping semantics). + auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy); + auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.TotalOffset); + + llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; + + if (PerformNullCheck) { + // In C++, if the base pointer evaluates to a null pointer value, + // the only valid pointer this inbounds GEP can produce is also + // a null pointer, so the offset must also evaluate to zero. + // Likewise, if we have non-zero base pointer, we can not get null pointer + // as a result, so the offset can not be -intptr_t(BasePtr). + // In other words, both pointers are either null, or both are non-null, + // or the behaviour is undefined. + // + // C, however, is more strict in this regard, and gives more + // optimization opportunities: in C, additionally, nullptr+0 is undefined. + // So both the input to the 'gep inbounds' AND the output must not be null. + auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr); + auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP); + auto *Valid = + CGM.getLangOpts().CPlusPlus + ? Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr) + : Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr); + Checks.emplace_back(Valid, SanitizerKind::PointerOverflow); + } + + if (PerformOverflowCheck) { + // The GEP is valid if: + // 1) The total offset doesn't overflow, and + // 2) The sign of the difference between the computed address and the base + // pointer matches the sign of the total offset. + llvm::Value *ValidGEP; + auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.OffsetOverflows); + if (SignedIndices) { + // GEP is computed as `unsigned base + signed offset`, therefore: + // * If offset was positive, then the computed pointer can not be + // [unsigned] less than the base pointer, unless it overflowed. + // * If offset was negative, then the computed pointer can not be + // [unsigned] greater than the bas pointere, unless it overflowed. + auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr); + auto *PosOrZeroOffset = + Builder.CreateICmpSGE(EvaluatedGEP.TotalOffset, Zero); + llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr); + ValidGEP = + Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid); + } else if (!IsSubtraction) { + // GEP is computed as `unsigned base + unsigned offset`, therefore the + // computed pointer can not be [unsigned] less than base pointer, + // unless there was an overflow. + // Equivalent to `@llvm.uadd.with.overflow(%base, %offset)`. + ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr); + } else { + // GEP is computed as `unsigned base - unsigned offset`, therefore the + // computed pointer can not be [unsigned] greater than base pointer, + // unless there was an overflow. + // Equivalent to `@llvm.usub.with.overflow(%base, sub(0, %offset))`. + ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr); + } + ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow); + Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow); + } + + assert(!Checks.empty() && "Should have produced some checks."); + + llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)}; + // Pass the computed GEP to the runtime to avoid emitting poisoned arguments. + llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP}; + EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs); + + return GEPVal; +} |