diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp | 271 |
1 files changed, 223 insertions, 48 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp index 2673e4a5cee7..2b2e23f1e5d7 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp @@ -31,6 +31,7 @@ #include "clang/AST/StmtObjC.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" @@ -52,6 +53,10 @@ using namespace clang; using namespace CodeGen; +namespace llvm { +extern cl::opt<bool> EnableSingleByteCoverage; +} // namespace llvm + /// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time /// markers. static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, @@ -86,6 +91,8 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) CodeGenFunction::~CodeGenFunction() { assert(LifetimeExtendedCleanupStack.empty() && "failed to emit a cleanup"); + assert(DeferredDeactivationCleanupStack.empty() && + "missed to deactivate a cleanup"); if (getLangOpts().OpenMP && CurFn) CGM.getOpenMPRuntime().functionFinished(*this); @@ -188,26 +195,47 @@ CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() { CGF.Builder.setDefaultConstrainedRounding(OldRounding); } -LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { +static LValue +makeNaturalAlignAddrLValue(llvm::Value *V, QualType T, bool ForPointeeType, + bool MightBeSigned, CodeGenFunction &CGF, + KnownNonNull_t IsKnownNonNull = NotKnownNonNull) { LValueBaseInfo BaseInfo; TBAAAccessInfo TBAAInfo; - CharUnits Alignment = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo); - Address Addr(V, ConvertTypeForMem(T), Alignment); - return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo); + CharUnits Alignment = + CGF.CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, ForPointeeType); + Address Addr = + MightBeSigned + ? CGF.makeNaturalAddressForPointer(V, T, Alignment, false, nullptr, + nullptr, IsKnownNonNull) + : Address(V, CGF.ConvertTypeForMem(T), Alignment, IsKnownNonNull); + return CGF.MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo); +} + +LValue +CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, + KnownNonNull_t IsKnownNonNull) { + return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, + /*MightBeSigned*/ true, *this, + IsKnownNonNull); } -/// Given a value of type T* that may not be to a complete object, -/// construct an l-value with the natural pointee alignment of T. LValue CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) { - LValueBaseInfo BaseInfo; - TBAAAccessInfo TBAAInfo; - CharUnits Align = CGM.getNaturalTypeAlignment(T, &BaseInfo, &TBAAInfo, - /* forPointeeType= */ true); - Address Addr(V, ConvertTypeForMem(T), Align); - return MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo); + return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, + /*MightBeSigned*/ true, *this); } +LValue CodeGenFunction::MakeNaturalAlignRawAddrLValue(llvm::Value *V, + QualType T) { + return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ false, + /*MightBeSigned*/ false, *this); +} + +LValue CodeGenFunction::MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, + QualType T) { + return ::makeNaturalAlignAddrLValue(V, T, /*ForPointeeType*/ true, + /*MightBeSigned*/ false, *this); +} llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) { return CGM.getTypes().ConvertTypeForMem(T); @@ -217,6 +245,11 @@ llvm::Type *CodeGenFunction::ConvertType(QualType T) { return CGM.getTypes().ConvertType(T); } +llvm::Type *CodeGenFunction::convertTypeForLoadStore(QualType ASTTy, + llvm::Type *LLVMTy) { + return CGM.getTypes().convertTypeForLoadStore(ASTTy, LLVMTy); +} + TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) { type = type.getCanonicalType(); while (true) { @@ -262,6 +295,7 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) { case Type::Record: case Type::ObjCObject: case Type::ObjCInterface: + case Type::ArrayParameter: return TEK_Aggregate; // We operate on atomic values according to their underlying type. @@ -331,6 +365,16 @@ static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) { void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { assert(BreakContinueStack.empty() && "mismatched push/pop in break/continue stack!"); + assert(LifetimeExtendedCleanupStack.empty() && + "mismatched push/pop of cleanups in EHStack!"); + assert(DeferredDeactivationCleanupStack.empty() && + "mismatched activate/deactivate of cleanups!"); + + if (CGM.shouldEmitConvergenceTokens()) { + ConvergenceTokenStack.pop_back(); + assert(ConvergenceTokenStack.empty() && + "mismatched push/pop in convergence stack!"); + } bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0 && NumSimpleReturnExprs == NumReturnExprs @@ -520,7 +564,8 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { ReturnBlock.getBlock()->eraseFromParent(); } if (ReturnValue.isValid()) { - auto *RetAlloca = dyn_cast<llvm::AllocaInst>(ReturnValue.getPointer()); + auto *RetAlloca = + dyn_cast<llvm::AllocaInst>(ReturnValue.emitRawPointer(*this)); if (RetAlloca && RetAlloca->use_empty()) { RetAlloca->eraseFromParent(); ReturnValue = Address::invalid(); @@ -790,6 +835,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); if (SanOpts.has(SanitizerKind::Thread)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); + if (SanOpts.has(SanitizerKind::NumericalStability)) + Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability); if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) Fn->addFnAttr(llvm::Attribute::SanitizeMemory); } @@ -806,7 +853,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // .cxx_destruct, __destroy_helper_block_ and all of their calees at run time. if (SanOpts.has(SanitizerKind::Thread)) { if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) { - IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0); + const IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0); if (OMD->getMethodFamily() == OMF_dealloc || OMD->getMethodFamily() == OMF_initialize || (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) { @@ -831,6 +878,17 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) SanOpts.Mask &= ~SanitizerKind::Null; + // Add pointer authentication attributes. + const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts(); + if (CodeGenOpts.PointerAuth.ReturnAddresses) + Fn->addFnAttr("ptrauth-returns"); + if (CodeGenOpts.PointerAuth.FunctionPointers) + Fn->addFnAttr("ptrauth-calls"); + if (CodeGenOpts.PointerAuth.AuthTraps) + Fn->addFnAttr("ptrauth-auth-traps"); + if (CodeGenOpts.PointerAuth.IndirectGotos) + Fn->addFnAttr("ptrauth-indirect-gotos"); + // Apply xray attributes to the function (as a string, for now) bool AlwaysXRayAttr = false; if (const auto *XRayAttr = D ? D->getAttr<XRayInstrumentAttr>() : nullptr) { @@ -937,6 +995,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (D && D->hasAttr<NoProfileFunctionAttr>()) Fn->addFnAttr(llvm::Attribute::NoProfile); + if (D && D->hasAttr<HybridPatchableAttr>()) + Fn->addFnAttr(llvm::Attribute::HybridPatchable); + if (D) { // Function attributes take precedence over command line flags. if (auto *A = D->getAttr<FunctionReturnThunksAttr>()) { @@ -957,6 +1018,11 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, EmitKernelMetadata(FD, Fn); } + if (FD && FD->hasAttr<ClspvLibclcBuiltinAttr>()) { + Fn->setMetadata("clspv_libclc_builtin", + llvm::MDNode::get(getLLVMContext(), {})); + } + // If we are checking function types, emit a function type signature as // prologue data. if (FD && SanOpts.has(SanitizerKind::Function)) { @@ -974,7 +1040,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // return value. Initialize the flag to 'true' and refine it in EmitParmDecl. if (SanOpts.has(SanitizerKind::NullabilityReturn)) { auto Nullability = FnRetTy->getNullability(); - if (Nullability && *Nullability == NullabilityKind::NonNull) { + if (Nullability && *Nullability == NullabilityKind::NonNull && + !FnRetTy->isRecordType()) { if (!(SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) && CurCodeDecl && CurCodeDecl->getAttr<ReturnsNonNullAttr>())) RetValNullabilityPrecondition = @@ -1117,13 +1184,14 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, auto AI = CurFn->arg_begin(); if (CurFnInfo->getReturnInfo().isSRetAfterThis()) ++AI; - ReturnValue = - Address(&*AI, ConvertType(RetTy), - CurFnInfo->getReturnInfo().getIndirectAlign(), KnownNonNull); + ReturnValue = makeNaturalAddressForPointer( + &*AI, RetTy, CurFnInfo->getReturnInfo().getIndirectAlign(), false, + nullptr, nullptr, KnownNonNull); if (!CurFnInfo->getReturnInfo().getIndirectByVal()) { - ReturnValuePointer = CreateDefaultAlignTempAlloca( - ReturnValue.getPointer()->getType(), "result.ptr"); - Builder.CreateStore(ReturnValue.getPointer(), ReturnValuePointer); + ReturnValuePointer = + CreateDefaultAlignTempAlloca(ReturnValue.getType(), "result.ptr"); + Builder.CreateStore(ReturnValue.emitRawPointer(*this), + ReturnValuePointer); } } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca && !hasScalarEvaluationKind(CurFnInfo->getReturnType())) { @@ -1184,8 +1252,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // or contains the address of the enclosing object). LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField); if (!LambdaThisCaptureField->getType()->isPointerType()) { - // If the enclosing object was captured by value, just use its address. - CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer(); + // If the enclosing object was captured by value, just use its + // address. Sign this pointer. + CXXThisValue = ThisFieldLValue.getPointer(*this); } else { // Load the lvalue pointed to by the field, since '*this' was captured // by reference. @@ -1252,6 +1321,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (CurFuncDecl) if (const auto *VecWidth = CurFuncDecl->getAttr<MinVectorWidthAttr>()) LargestVectorWidth = VecWidth->getVectorWidth(); + + if (CGM.shouldEmitConvergenceTokens()) + ConvergenceTokenStack.push_back(getOrEmitConvergenceEntryToken(CurFn)); } void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { @@ -1270,7 +1342,10 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S) { llvm::BasicBlock *SkipCountBB = nullptr; - if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr()) { + // Do not skip over the instrumentation when single byte coverage mode is + // enabled. + if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr() && + !llvm::EnableSingleByteCoverage) { // When instrumenting for profiling, the fallthrough to certain // statements needs to skip over the instrumentation code so that we // get an accurate count. @@ -1353,6 +1428,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, FunctionArgList Args; QualType ResTy = BuildFunctionArgList(GD, Args); + CGM.getTargetCodeGenInfo().checkFunctionABI(CGM, FD); + if (FD->isInlineBuiltinDeclaration()) { // When generating code for a builtin with an inline declaration, use a // mangled name to hold the actual body, while keeping an external @@ -1441,6 +1518,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, // Ensure that the function adheres to the forward progress guarantee, which // is required by certain optimizations. + // In C++11 and up, the attribute will be removed if the body contains a + // trivial empty loop. if (checkIfFunctionMustProgress()) CurFn->addFnAttr(llvm::Attribute::MustProgress); @@ -2002,8 +2081,9 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, = llvm::ConstantInt::get(CGF.IntPtrTy, baseSize.getQuantity()); Address begin = dest.withElementType(CGF.Int8Ty); - llvm::Value *end = Builder.CreateInBoundsGEP( - begin.getElementType(), begin.getPointer(), sizeInChars, "vla.end"); + llvm::Value *end = Builder.CreateInBoundsGEP(begin.getElementType(), + begin.emitRawPointer(CGF), + sizeInChars, "vla.end"); llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock(); llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop"); @@ -2014,7 +2094,7 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, CGF.EmitBlock(loopBB); llvm::PHINode *cur = Builder.CreatePHI(begin.getType(), 2, "vla.cur"); - cur->addIncoming(begin.getPointer(), originBB); + cur->addIncoming(begin.emitRawPointer(CGF), originBB); CharUnits curAlign = dest.getAlignment().alignmentOfArrayElement(baseSize); @@ -2179,8 +2259,8 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, dyn_cast<llvm::ArrayType>(addr.getElementType()); while (llvmArrayType) { assert(isa<ConstantArrayType>(arrayType)); - assert(cast<ConstantArrayType>(arrayType)->getSize().getZExtValue() - == llvmArrayType->getNumElements()); + assert(cast<ConstantArrayType>(arrayType)->getZExtSize() == + llvmArrayType->getNumElements()); gepIndices.push_back(zero); countFromCLAs *= llvmArrayType->getNumElements(); @@ -2198,8 +2278,7 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, // as some other type (probably a packed struct). Compute the array // size, and just emit the 'begin' expression as a bitcast. while (arrayType) { - countFromCLAs *= - cast<ConstantArrayType>(arrayType)->getSize().getZExtValue(); + countFromCLAs *= cast<ConstantArrayType>(arrayType)->getZExtSize(); eltType = arrayType->getElementType(); arrayType = getContext().getAsArrayType(eltType); } @@ -2208,10 +2287,10 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, addr = addr.withElementType(baseType); } else { // Create the actual GEP. - addr = Address(Builder.CreateInBoundsGEP( - addr.getElementType(), addr.getPointer(), gepIndices, "array.begin"), - ConvertTypeForMem(eltType), - addr.getAlignment()); + addr = Address(Builder.CreateInBoundsGEP(addr.getElementType(), + addr.emitRawPointer(*this), + gepIndices, "array.begin"), + ConvertTypeForMem(eltType), addr.getAlignment()); } baseType = eltType; @@ -2339,6 +2418,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { type = cast<MemberPointerType>(ty)->getPointeeType(); break; + case Type::ArrayParameter: case Type::ConstantArray: case Type::IncompleteArray: // Losing element qualification here is fine. @@ -2399,6 +2479,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { case Type::BTFTagAttributed: case Type::SubstTemplateTypeParm: case Type::MacroQualified: + case Type::CountAttributed: // Keep walking after single level desugaring. type = type.getSingleStepDesugaredType(getContext()); break; @@ -2407,6 +2488,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { case Type::Decltype: case Type::Auto: case Type::DeducedTemplateSpecialization: + case Type::PackIndexing: // Stop walking: nothing to do. return; @@ -2429,11 +2511,11 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { Address CodeGenFunction::EmitVAListRef(const Expr* E) { if (getContext().getBuiltinVaListType()->isArrayType()) return EmitPointerWithAlignment(E); - return EmitLValue(E).getAddress(*this); + return EmitLValue(E).getAddress(); } Address CodeGenFunction::EmitMSVAListRef(const Expr *E) { - return EmitLValue(E).getAddress(*this); + return EmitLValue(E).getAddress(); } void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E, @@ -2550,7 +2632,7 @@ void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) { Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, Address Addr) { assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute"); - llvm::Value *V = Addr.getPointer(); + llvm::Value *V = Addr.emitRawPointer(*this); llvm::Type *VTy = V->getType(); auto *PTy = dyn_cast<llvm::PointerType>(VTy); unsigned AS = PTy ? PTy->getAddressSpace() : 0; @@ -2586,7 +2668,6 @@ CodeGenFunction::SanitizerScope::~SanitizerScope() { void CodeGenFunction::InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, - llvm::BasicBlock *BB, llvm::BasicBlock::iterator InsertPt) const { LoopStack.InsertHelper(I); if (IsSanitizerScope) @@ -2594,17 +2675,35 @@ void CodeGenFunction::InsertHelper(llvm::Instruction *I, } void CGBuilderInserter::InsertHelper( - llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB, + llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const { - llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt); + llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, InsertPt); if (CGF) - CGF->InsertHelper(I, Name, BB, InsertPt); + CGF->InsertHelper(I, Name, InsertPt); } // Emits an error if we don't have a valid set of target features for the // called function. void CodeGenFunction::checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl) { + // SemaChecking cannot handle below x86 builtins because they have different + // parameter ranges with different TargetAttribute of caller. + if (CGM.getContext().getTargetInfo().getTriple().isX86()) { + unsigned BuiltinID = TargetDecl->getBuiltinID(); + if (BuiltinID == X86::BI__builtin_ia32_cmpps || + BuiltinID == X86::BI__builtin_ia32_cmpss || + BuiltinID == X86::BI__builtin_ia32_cmppd || + BuiltinID == X86::BI__builtin_ia32_cmpsd) { + const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl); + llvm::StringMap<bool> TargetFetureMap; + CGM.getContext().getFunctionFeatureMap(TargetFetureMap, FD); + llvm::APSInt Result = + *(E->getArg(2)->getIntegerConstantExpr(CGM.getContext())); + if (Result.getSExtValue() > 7 && !TargetFetureMap.lookup("avx")) + CGM.getDiags().Report(E->getBeginLoc(), diag::err_builtin_needs_feature) + << TargetDecl->getDeclName() << "avx"; + } + } return checkTargetFeatures(E->getBeginLoc(), TargetDecl); } @@ -2707,11 +2806,8 @@ void CodeGenFunction::EmitKCFIOperandBundle( llvm::Value *CodeGenFunction::FormAArch64ResolverCondition( const MultiVersionResolverOption &RO) { llvm::SmallVector<StringRef, 8> CondFeatures; - for (const StringRef &Feature : RO.Conditions.Features) { - // Form condition for features which are not yet enabled in target - if (!getContext().getTargetInfo().hasFeature(Feature)) - CondFeatures.push_back(Feature); - } + for (const StringRef &Feature : RO.Conditions.Features) + CondFeatures.push_back(Feature); if (!CondFeatures.empty()) { return EmitAArch64CpuSupports(CondFeatures); } @@ -2879,7 +2975,7 @@ void CodeGenFunction::emitAlignmentAssumptionCheck( SourceLocation SecondaryLoc, llvm::Value *Alignment, llvm::Value *OffsetValue, llvm::Value *TheCheck, llvm::Instruction *Assumption) { - assert(Assumption && isa<llvm::CallInst>(Assumption) && + assert(isa_and_nonnull<llvm::CallInst>(Assumption) && cast<llvm::CallInst>(Assumption)->getCalledOperand() == llvm::Intrinsic::getDeclaration( Builder.GetInsertBlock()->getParent()->getParent(), @@ -2969,3 +3065,82 @@ llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec, return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name); } + +void CodeGenFunction::EmitPointerAuthOperandBundle( + const CGPointerAuthInfo &PointerAuth, + SmallVectorImpl<llvm::OperandBundleDef> &Bundles) { + if (!PointerAuth.isSigned()) + return; + + auto *Key = Builder.getInt32(PointerAuth.getKey()); + + llvm::Value *Discriminator = PointerAuth.getDiscriminator(); + if (!Discriminator) + Discriminator = Builder.getSize(0); + + llvm::Value *Args[] = {Key, Discriminator}; + Bundles.emplace_back("ptrauth", Args); +} + +static llvm::Value *EmitPointerAuthCommon(CodeGenFunction &CGF, + const CGPointerAuthInfo &PointerAuth, + llvm::Value *Pointer, + unsigned IntrinsicID) { + if (!PointerAuth) + return Pointer; + + auto Key = CGF.Builder.getInt32(PointerAuth.getKey()); + + llvm::Value *Discriminator = PointerAuth.getDiscriminator(); + if (!Discriminator) { + Discriminator = CGF.Builder.getSize(0); + } + + // Convert the pointer to intptr_t before signing it. + auto OrigType = Pointer->getType(); + Pointer = CGF.Builder.CreatePtrToInt(Pointer, CGF.IntPtrTy); + + // call i64 @llvm.ptrauth.sign.i64(i64 %pointer, i32 %key, i64 %discriminator) + auto Intrinsic = CGF.CGM.getIntrinsic(IntrinsicID); + Pointer = CGF.EmitRuntimeCall(Intrinsic, {Pointer, Key, Discriminator}); + + // Convert back to the original type. + Pointer = CGF.Builder.CreateIntToPtr(Pointer, OrigType); + return Pointer; +} + +llvm::Value * +CodeGenFunction::EmitPointerAuthSign(const CGPointerAuthInfo &PointerAuth, + llvm::Value *Pointer) { + if (!PointerAuth.shouldSign()) + return Pointer; + return EmitPointerAuthCommon(*this, PointerAuth, Pointer, + llvm::Intrinsic::ptrauth_sign); +} + +static llvm::Value *EmitStrip(CodeGenFunction &CGF, + const CGPointerAuthInfo &PointerAuth, + llvm::Value *Pointer) { + auto StripIntrinsic = CGF.CGM.getIntrinsic(llvm::Intrinsic::ptrauth_strip); + + auto Key = CGF.Builder.getInt32(PointerAuth.getKey()); + // Convert the pointer to intptr_t before signing it. + auto OrigType = Pointer->getType(); + Pointer = CGF.EmitRuntimeCall( + StripIntrinsic, {CGF.Builder.CreatePtrToInt(Pointer, CGF.IntPtrTy), Key}); + return CGF.Builder.CreateIntToPtr(Pointer, OrigType); +} + +llvm::Value * +CodeGenFunction::EmitPointerAuthAuth(const CGPointerAuthInfo &PointerAuth, + llvm::Value *Pointer) { + if (PointerAuth.shouldStrip()) { + return EmitStrip(*this, PointerAuth, Pointer); + } + if (!PointerAuth.shouldAuth()) { + return Pointer; + } + + return EmitPointerAuthCommon(*this, PointerAuth, Pointer, + llvm::Intrinsic::ptrauth_auth); +} |