llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Ahmed Bougacha (ahmedbougacha) <details> <summary>Changes</summary> The functions are currently always signed/authenticated with zero discriminator. Co-Authored-By: John McCall <rjmccall@<!-- -->apple.com> --- Patch is 37.62 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/93906.diff 24 Files Affected: - (modified) clang/include/clang/Basic/CodeGenOptions.h (+4) - (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+3) - (modified) clang/include/clang/Basic/LangOptions.h (+2) - (modified) clang/include/clang/Basic/PointerAuthOptions.h (+136) - (modified) clang/include/clang/Frontend/CompilerInvocation.h (+10) - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+1-2) - (modified) clang/lib/CodeGen/CGCall.cpp (+3) - (modified) clang/lib/CodeGen/CGCall.h (+22-6) - (modified) clang/lib/CodeGen/CGExpr.cpp (+9-8) - (modified) clang/lib/CodeGen/CGExprConstant.cpp (+18-1) - (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+51) - (added) clang/lib/CodeGen/CGPointerAuthInfo.h (+96) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+22) - (modified) clang/lib/CodeGen/CodeGenFunction.h (+7) - (modified) clang/lib/CodeGen/CodeGenModule.h (+34) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+36) - (modified) clang/lib/Headers/ptrauth.h (+34) - (added) clang/test/CodeGen/ptrauth-function-attributes.c (+13) - (added) clang/test/CodeGen/ptrauth-function-init-fail.c (+5) - (added) clang/test/CodeGen/ptrauth-function-init.c (+31) - (added) clang/test/CodeGen/ptrauth-function-lvalue-cast.c (+23) - (added) clang/test/CodeGen/ptrauth-function.c (+28) - (added) clang/test/CodeGen/ptrauth-weak_import.c (+10) - (added) clang/test/CodeGenCXX/ptrauth.cpp (+24) ``````````diff diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 9469a424045bb..502722a6ec4eb 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H #define LLVM_CLANG_BASIC_CODEGENOPTIONS_H +#include "clang/Basic/PointerAuthOptions.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/XRayInstr.h" #include "llvm/ADT/FloatingPointMode.h" @@ -388,6 +389,9 @@ class CodeGenOptions : public CodeGenOptionsBase { std::vector<std::string> Reciprocals; + /// Configuration for pointer-signing. + PointerAuthOptions PointerAuth; + /// The preferred width for auto-vectorization transforms. This is intended to /// override default transforms based on the width of the architected vector /// registers. diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 773b234cd68fe..6cbb0c8401c15 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -351,6 +351,9 @@ def err_drv_omp_host_ir_file_not_found : Error< "target regions but cannot be found">; def err_drv_omp_host_target_not_supported : Error< "target '%0' is not a supported OpenMP host target">; +def err_drv_ptrauth_not_supported : Error< + "target '%0' does not support native pointer authentication">; + def err_drv_expecting_fopenmp_with_fopenmp_targets : Error< "'-fopenmp-targets' must be used in conjunction with a '-fopenmp' option " "compatible with offloading; e.g., '-fopenmp=libomp' or '-fopenmp=libiomp5'">; diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 75e88afbd9705..5216822e45b1b 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -346,6 +346,8 @@ class LangOptionsBase { BKey }; + using PointerAuthenticationMode = ::clang::PointerAuthenticationMode; + enum class ThreadModelKind { /// POSIX Threads. POSIX, diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h index e5cdcc31ebfb7..32b179e3f9460 100644 --- a/clang/include/clang/Basic/PointerAuthOptions.h +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include <map> +#include <memory> +#include <string> +#include <vector> + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { + None, + ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { + ASIA = 0, + ASIB = 1, + ASDA = 2, + ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { + /// No additional discrimination. + None, + + /// Discriminate using a constant value. + Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; + unsigned IsIsaPointer : 1; + unsigned AuthenticatesNullValues : 1; + PointerAuthenticationMode SelectedAuthenticationMode : 2; + Discrimination DiscriminationKind : 2; + unsigned Key : 4; + unsigned ConstantDiscriminator : 16; + +public: + PointerAuthSchema() : TheKind(Kind::None) {} + + PointerAuthSchema( + ARM8_3Key Key, bool IsAddressDiscriminated, + PointerAuthenticationMode AuthenticationMode, + Discrimination OtherDiscrimination, + std::optional<uint16_t> ConstantDiscriminatorOrNone = std::nullopt, + bool IsIsaPointer = false, bool AuthenticatesNullValues = false) + : TheKind(Kind::ARM8_3), IsAddressDiscriminated(IsAddressDiscriminated), + IsIsaPointer(IsIsaPointer), + AuthenticatesNullValues(AuthenticatesNullValues), + SelectedAuthenticationMode(AuthenticationMode), + DiscriminationKind(OtherDiscrimination), Key(unsigned(Key)) { + assert((getOtherDiscrimination() != Discrimination::Constant || + ConstantDiscriminatorOrNone) && + "constant discrimination requires a constant!"); + if (ConstantDiscriminatorOrNone) + ConstantDiscriminator = *ConstantDiscriminatorOrNone; + } + + PointerAuthSchema( + ARM8_3Key Key, bool IsAddressDiscriminated, + Discrimination OtherDiscrimination, + std::optional<uint16_t> ConstantDiscriminatorOrNone = std::nullopt, + bool IsIsaPointer = false, bool AuthenticatesNullValues = false) + : PointerAuthSchema(Key, IsAddressDiscriminated, + PointerAuthenticationMode::SignAndAuth, + OtherDiscrimination, ConstantDiscriminatorOrNone, + IsIsaPointer, AuthenticatesNullValues) {} + + Kind getKind() const { return TheKind; } + + explicit operator bool() const { return isEnabled(); } + + bool isEnabled() const { return getKind() != Kind::None; } + + bool isAddressDiscriminated() const { + assert(getKind() != Kind::None); + return IsAddressDiscriminated; + } + + bool isIsaPointer() const { + assert(getKind() != Kind::None); + return IsIsaPointer; + } + + bool authenticatesNullValues() const { + assert(getKind() != Kind::None); + return AuthenticatesNullValues; + } + + bool hasOtherDiscrimination() const { + return getOtherDiscrimination() != Discrimination::None; + } + + Discrimination getOtherDiscrimination() const { + assert(getKind() != Kind::None); + return DiscriminationKind; + } + + uint16_t getConstantDiscrimination() const { + assert(getOtherDiscrimination() == Discrimination::Constant); + return (uint16_t)ConstantDiscriminator; + } + + unsigned getKey() const { + switch (getKind()) { + case Kind::None: + llvm_unreachable("calling getKey() on disabled schema"); + case Kind::ARM8_3: + return unsigned(getARM8_3Key()); + } + llvm_unreachable("bad key kind"); + } + + PointerAuthenticationMode getAuthenticationMode() const { + return SelectedAuthenticationMode; + } + + ARM8_3Key getARM8_3Key() const { + assert(getKind() == Kind::ARM8_3); + return ARM8_3Key(Key); + } +}; + +struct PointerAuthOptions { + /// The ABI for C function pointers. + PointerAuthSchema FunctionPointers; +}; + } // end namespace clang #endif diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index 1a2a39411e58d..e60e5aad6c70d 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -305,6 +305,16 @@ class CompilerInvocation : public CompilerInvocationBase { /// executable), for finding the builtin compiler path. static std::string GetResourcesPath(const char *Argv0, void *MainAddr); + /// Populate \p Opts with the default set of pointer authentication-related + /// options given \p LangOpts and \p Triple. Return true if defaults are + /// available. + /// + /// Note: This is intended to be used by tools which must be aware of + /// pointer authentication-related code generation, e.g. lldb. + static bool setDefaultPointerAuthOptions(PointerAuthOptions &Opts, + const LangOptions &LangOpts, + const llvm::Triple &Triple); + /// Retrieve a module hash string that is suitable for uniquely /// identifying the conditions under which the module was built. std::string getModuleHash() const; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index b2e3b6fa64284..1f528f9490cd2 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5999,8 +5999,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // If this is a predefined lib function (e.g. malloc), emit the call // using exactly the normal call path. if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) - return emitLibraryCall( - *this, FD, E, cast<llvm::Constant>(EmitScalarExpr(E->getCallee()))); + return emitLibraryCall(*this, FD, E, CGM.getRawFunctionPointer(FD)); // Check that a call to a target specific builtin has the correct target // features. diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 97449a5e51e73..c33f37bf5b8c4 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5677,6 +5677,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, !isa_and_nonnull<FunctionDecl>(TargetDecl)) EmitKCFIOperandBundle(ConcreteCallee, BundleList); + // Add the pointer-authentication bundle. + EmitPointerAuthOperandBundle(ConcreteCallee.getPointerAuthInfo(), BundleList); + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) if (FD->hasAttr<StrictFPAttr>()) // All calls within a strictfp function are marked strictfp diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index 6b676ac196db2..4b0e1561b4ef5 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGCALL_H #define LLVM_CLANG_LIB_CODEGEN_CGCALL_H +#include "CGPointerAuthInfo.h" #include "CGValue.h" #include "EHScopeStack.h" #include "clang/AST/ASTFwd.h" @@ -69,6 +70,10 @@ class CGCallee { Last = Virtual }; + struct OrdinaryInfoStorage { + CGCalleeInfo AbstractInfo; + CGPointerAuthInfo PointerAuthInfo; + }; struct BuiltinInfoStorage { const FunctionDecl *Decl; unsigned ID; @@ -85,7 +90,7 @@ class CGCallee { SpecialKind KindOrFunctionPointer; union { - CGCalleeInfo AbstractInfo; + OrdinaryInfoStorage OrdinaryInfo; BuiltinInfoStorage BuiltinInfo; PseudoDestructorInfoStorage PseudoDestructorInfo; VirtualInfoStorage VirtualInfo; @@ -104,10 +109,13 @@ class CGCallee { /// Construct a callee. Call this constructor directly when this /// isn't a direct call. - CGCallee(const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr) + CGCallee( + const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr, + const CGPointerAuthInfo &pointerAuthInfo = /*FIXME*/ CGPointerAuthInfo()) : KindOrFunctionPointer( SpecialKind(reinterpret_cast<uintptr_t>(functionPtr))) { - AbstractInfo = abstractInfo; + OrdinaryInfo.AbstractInfo = abstractInfo; + OrdinaryInfo.PointerAuthInfo = pointerAuthInfo; assert(functionPtr && "configuring callee without function pointer"); assert(functionPtr->getType()->isPointerTy()); } @@ -128,12 +136,12 @@ class CGCallee { static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo = CGCalleeInfo()) { - return CGCallee(abstractInfo, functionPtr); + return CGCallee(abstractInfo, functionPtr, CGPointerAuthInfo()); } static CGCallee forDirect(llvm::FunctionCallee functionPtr, const CGCalleeInfo &abstractInfo = CGCalleeInfo()) { - return CGCallee(abstractInfo, functionPtr.getCallee()); + return CGCallee(abstractInfo, functionPtr.getCallee(), CGPointerAuthInfo()); } static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, @@ -173,7 +181,11 @@ class CGCallee { if (isVirtual()) return VirtualInfo.MD; assert(isOrdinary()); - return AbstractInfo; + return OrdinaryInfo.AbstractInfo; + } + const CGPointerAuthInfo &getPointerAuthInfo() const { + assert(isOrdinary()); + return OrdinaryInfo.PointerAuthInfo; } llvm::Value *getFunctionPointer() const { assert(isOrdinary()); @@ -184,6 +196,10 @@ class CGCallee { KindOrFunctionPointer = SpecialKind(reinterpret_cast<uintptr_t>(functionPtr)); } + void setPointerAuthInfo(CGPointerAuthInfo pointerAuth) { + assert(isOrdinary()); + OrdinaryInfo.PointerAuthInfo = pointerAuth; + } bool isVirtual() const { return KindOrFunctionPointer == SpecialKind::Virtual; diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index d6478cc6835d8..152f51f5865e0 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2850,22 +2850,22 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, return LV; } -static llvm::Constant *EmitFunctionDeclPointer(CodeGenModule &CGM, - GlobalDecl GD) { +llvm::Constant *CodeGenModule::getRawFunctionPointer(GlobalDecl GD, + llvm::Type *Ty) { const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); if (FD->hasAttr<WeakRefAttr>()) { - ConstantAddress aliasee = CGM.GetWeakRefReference(FD); + ConstantAddress aliasee = GetWeakRefReference(FD); return aliasee.getPointer(); } - llvm::Constant *V = CGM.GetAddrOfFunction(GD); + llvm::Constant *V = GetAddrOfFunction(GD, Ty); return V; } static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF, const Expr *E, GlobalDecl GD) { const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); - llvm::Value *V = EmitFunctionDeclPointer(CGF.CGM, GD); + llvm::Constant *V = CGF.CGM.getFunctionPointer(GD); CharUnits Alignment = CGF.getContext().getDeclAlign(FD); return CGF.MakeAddrLValue(V, E->getType(), Alignment, AlignmentSource::Decl); @@ -5501,7 +5501,7 @@ static CGCallee EmitDirectCallee(CodeGenFunction &CGF, GlobalDecl GD) { // name to make it clear it's not the actual builtin. if (CGF.CurFn->getName() != FDInlineName && OnlyHasInlineBuiltinDeclaration(FD)) { - llvm::Constant *CalleePtr = EmitFunctionDeclPointer(CGF.CGM, GD); + llvm::Constant *CalleePtr = CGF.CGM.getRawFunctionPointer(GD); llvm::Function *Fn = llvm::cast<llvm::Function>(CalleePtr); llvm::Module *M = Fn->getParent(); llvm::Function *Clone = M->getFunction(FDInlineName); @@ -5524,7 +5524,7 @@ static CGCallee EmitDirectCallee(CodeGenFunction &CGF, GlobalDecl GD) { return CGCallee::forBuiltin(builtinID, FD); } - llvm::Constant *CalleePtr = EmitFunctionDeclPointer(CGF.CGM, GD); + llvm::Constant *CalleePtr = CGF.CGM.getRawFunctionPointer(GD); if (CGF.CGM.getLangOpts().CUDA && !CGF.CGM.getLangOpts().CUDAIsDevice && FD->hasAttr<CUDAGlobalAttr>()) CalleePtr = CGF.CGM.getCUDARuntime().getKernelStub( @@ -5581,7 +5581,8 @@ CGCallee CodeGenFunction::EmitCallee(const Expr *E) { GD = GlobalDecl(VD); CGCalleeInfo calleeInfo(functionType->getAs<FunctionProtoType>(), GD); - CGCallee callee(calleeInfo, calleePtr); + CGPointerAuthInfo pointerAuth = CGM.getFunctionPointerAuthInfo(functionType); + CGCallee callee(calleeInfo, calleePtr, pointerAuth); return callee; } diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index de9380c0e63be..bfb545a2fe1f6 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1956,8 +1956,25 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) { if (D->hasAttr<WeakRefAttr>()) return CGM.GetWeakRefReference(D).getPointer(); + auto PtrAuthSign = [&](llvm::Constant *C) { + CGPointerAuthInfo AuthInfo = CGM.getFunctionPointerAuthInfo(DestType); + + if (AuthInfo) { + if (hasNonZeroOffset()) + return ConstantLValue(nullptr); + + C = applyOffset(C); + C = CGM.getConstantSignedPointer( + C, AuthInfo.getKey(), nullptr, + cast_or_null<llvm::Constant>(AuthInfo.getDiscriminator())); + return ConstantLValue(C, /*applied offset*/ true); + } + + return ConstantLValue(C); + }; + if (auto FD = dyn_cast<FunctionDecl>(D)) - return CGM.GetAddrOfFunction(FD); + return PtrAuthSign(CGM.getRawFunctionPointer(FD)); if (auto VD = dyn_cast<VarDecl>(D)) { // We can never refer to a variable with local storage. diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp index 756c00aa42c8c..adfa721ac89d3 100644 --- a/clang/lib/CodeGen/CGPointerAuth.cpp +++ b/clang/lib/CodeGen/CGPointerAuth.cpp @@ -28,6 +28,24 @@ using namespace clang; using namespace CodeGen; +/// Return the abstract pointer authentication schema for a pointer to the given +/// function type. +CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) { + auto &Schema = getCodeGenOpts().PointerAuth.FunctionPointers; + if (!Schema) + return CGPointerAuthInfo(); + + assert(!Schema.isAddressDiscriminated() && + "function pointers cannot use address-specific discrimination"); + + assert(!Schema.hasOtherDiscrimination() && + "function pointers don't support any discrimination yet"); + + return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(), + /*IsaPointer=*/false, /*AuthenticatesNull=*/false, + /*Discriminator=*/nullptr); +} + /// Build a signed-pointer "ptrauth" constant. static llvm::ConstantPtrAuth * buildConstantAddress(CodeGenModule &CGM, llvm::Constant *pointer, unsigned key, @@ -75,3 +93,36 @@ CodeGen::getConstantSignedPointer(CodeGenModule &CGM, return CGM.getConstantSignedPointer(pointer, key, storageAddress, otherDiscriminator); } + +/// If applicable, sign a given constant function pointer with the ABI rules for +/// functionType. +llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *pointer, + QualType functionType, + GlobalDecl GD) { + assert(functionType->isFunctionType() || + functionType->isFunctionReferenceType() || + functionType->isFunctionPointerType()); + + if (auto pointerAuth = getFunctionPointerAuthInfo(functionType)) { + return getConstantSignedPointer( + pointer, pointerAuth.getKey(), nullptr, + cast_or_null<llvm::Constant>(pointerAuth.getDiscriminator())); + } + + return pointer; +} + +llvm::Constant *CodeGenModule::getFunctionPointer(GlobalDecl GD, + llvm::Type *Ty) { + const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); + + // Annoyingly, K&R functions have prototypes in the clang AST, but + // expressions referring to them are unprototyped. + QualType FuncType = FD->getType(); + if (!FD->hasPrototype()) + if (const auto *Proto = FuncType->getAs<FunctionProtoType>()) + FuncType = Context.getFunctionNoProtoType(Proto->getReturnType(), + Proto->getExtInfo()); + + return getFunctionPointer(getRawFunctionPointer(GD, Ty), FuncType, GD); +} diff --git a/clang/lib/CodeGen/CGPointerAuthInfo.h b/clang/lib/CodeGen/CGPointerAuthInfo.h new file mode 100644 index 0000000000000..e870c3145acba --- /dev/null +++ b/clang/lib/CodeGen/CGPointerAuthInfo.h @@ -0,0 +1,96 @@ +//===----- CGPointerAuthInfo.h - -------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Pointer auth info class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CGPOINTERAUTHINFO_H +#define LLVM_CLANG_LIB_CODEGEN_CGPOINTERAUTHINFO_H + +#include "clang/AST/Type.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" + +namespace clang { +namespace CodeGen { + +class CGPointerAuthInfo { +private: + PointerAuthenticationMode AuthenticationMode : 2; + bool IsIsaPointer : 1; + bool AuthenticatesNullValues : 1; + unsigned Key : 28; + llvm::Value *Discriminator; + +public: + CGPointerAuthInfo() + : AuthenticationMode(PointerAuthenticationMode... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/93906 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits