llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Oliver Hunt (ojhunt)

<details>
<summary>Changes</summary>

This PR adds support for an 'options' parameter for the __ptrauth qualifier.
The initial version only exposes the authehntication modes:
 * "strip"
 * "sign-and-strip"
 * "sign-and-auth"

We also support parsing the options but not yet the implementation
 * "isa-pointer"
 * "authenticates-null-values"

The initial support for authentication mode controls exist to support ABI 
changes over time, and as a byproduct support basic initial tests for option 
parsing.

---

Patch is 51.03 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/172187.diff


14 Files Affected:

- (modified) clang/docs/PointerAuthentication.rst (+28-4) 
- (modified) clang/include/clang/Basic/Attr.td (+3-3) 
- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+1-1) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+12) 
- (modified) clang/include/clang/Basic/LangOptions.h (+11) 
- (modified) clang/lib/AST/TypePrinter.cpp (+33-1) 
- (modified) clang/lib/CodeGen/CGExprConstant.cpp (+17-7) 
- (modified) clang/lib/Parse/ParseDecl.cpp (+1-1) 
- (modified) clang/lib/Sema/SemaType.cpp (+147-9) 
- (added) clang/test/CodeGen/ptrauth-stripping.c (+327) 
- (modified) clang/test/Parser/ptrauth-qualifier.c (+1-1) 
- (added) clang/test/Sema/ptrauth-qualifier-options.c (+108) 
- (modified) clang/test/Sema/ptrauth-qualifier.c (+33-6) 
- (added) clang/test/SemaCXX/ptrauth-qualifier-constexpr-options.cpp (+65) 


``````````diff
diff --git a/clang/docs/PointerAuthentication.rst 
b/clang/docs/PointerAuthentication.rst
index bf2520b32a3a4..899bca203a137 100644
--- a/clang/docs/PointerAuthentication.rst
+++ b/clang/docs/PointerAuthentication.rst
@@ -427,7 +427,7 @@ purposes they are all equivalent to ``ptrauth_calls``.
 ``__ptrauth`` qualifier
 ^^^^^^^^^^^^^^^^^^^^^^^
 
-``__ptrauth(key, address, discriminator)`` is an extended type
+``__ptrauth(key, address, discriminator, options)`` is an extended type
 qualifier which causes so-qualified objects to hold pointers or pointer sized
 integers signed using the specified schema rather than the default schema for
 such types.
@@ -452,6 +452,9 @@ The qualifier's operands are as follows:
 
 - ``discriminator`` - a constant discriminator; must be a constant expression
 
+- ``options`` - a constant string expression containing a list of comma
+  separated authentication options; see ``ptrauth_qualifier_options``_
+
 See `Discriminators`_ for more information about discriminators.
 
 Currently the operands must be constant-evaluable even within templates. In the
@@ -463,9 +466,9 @@ qualifiers on a parameter (after parameter type adjustment) 
are ignored when
 deriving the type of the function.  The parameter will be passed using the
 default ABI for the unqualified pointer type.
 
-If ``x`` is an object of type ``__ptrauth(key, address, discriminator) T``,
-then the signing schema of the value stored in ``x`` is a key of ``key`` and
-a discriminator determined as follows:
+If ``x`` is an object of type ``__ptrauth(key, address, discriminator, 
options) T``,
+then the signing schema of the value stored in ``x`` is a key of ``key`` and a
+discriminator determined as follows:
 
 - if ``address`` is 0, then the discriminator is ``discriminator``;
 
@@ -527,6 +530,27 @@ rules of C++:
   indirectly. Thus, changing the address-sensitivity of a type may be
   ABI-breaking even if its size and alignment do not change.
 
+``ptrauth_qualifier_options``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The options parameter to the ``__ptrauth`` qualifier is a string of comma
+separated modifiers to the normal authentication behavior. Currently supported
+options are
+
+- Authentication mode: This is one of ``strip``, ``sign-and-strip``, and
+  ``sign-and-auth``. The ability to modify this behavior is intended to support
+  staging ABI changes. The ``strip`` mode results in the PAC bits of a value
+  being stripped from any value and disabled any other authentication
+  operations. ``sign-and-strip`` strips an authenticated on read, but will
+  ensure a correct signature is set on assignment. Finally ``sign-and-auth`` is
+  the default mode, and provides full protection for the value.
+
+- ``authenticates-null-values``: By default the __ptrauth qualifier does not
+  sign the zero value. This permits fast implementation of null checks in the
+  common case where a null value is safe. The ``authenticates-null-values``
+  option overrides this behavior, and permits null values to be protected with
+  pointer authentication.
+
 ``<ptrauth.h>``
 ~~~~~~~~~~~~~~~
 
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 0b006142cbb74..d0d65fbe166f0 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3750,9 +3750,9 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
 
 def PointerAuth : TypeAttr {
   let Spellings = [CustomKeyword<"__ptrauth">];
-  let Args = [IntArgument<"Key">,
-              BoolArgument<"AddressDiscriminated", 1>,
-              IntArgument<"ExtraDiscriminator", 1>];
+  let Args = [IntArgument<"Key">, BoolArgument<"AddressDiscriminated", 1>,
+              IntArgument<"ExtraDiscriminator", 1>,
+              StringArgument<"Options", 1>];
   let Documentation = [PtrAuthDocs];
 }
 
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 442a90ec2472d..6abadc6d4655e 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1771,7 +1771,7 @@ def warn_pragma_unroll_cuda_value_in_parens : Warning<
   InGroup<CudaCompat>;
 
 def err_ptrauth_qualifier_bad_arg_count : Error<
-  "'__ptrauth' qualifier must take between 1 and 3 arguments">;
+  "'__ptrauth' qualifier must take between 1 and 4 arguments">;
 
 def warn_cuda_attr_lambda_position : Warning<
   "nvcc does not allow '__%0__' to appear after the parameter list in 
lambdas">,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 381d1fb063eba..c285e2d1e2a0d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1048,6 +1048,18 @@ def err_ptrauth_extra_discriminator_invalid : Error<
   "invalid extra discriminator flag '%0'; '__ptrauth' requires a value between 
"
   "'0' and '%1'">;
 
+// __ptrauth qualifier options string
+def note_ptrauth_evaluating_options
+    : Note<"options parameter evaluated to '%0'">;
+def err_ptrauth_invalid_option : Error<"'__ptrauth' options parameter %0">;
+def err_ptrauth_unknown_authentication_option
+    : Error<"unknown '__ptrauth' authentication option '%0'">;
+def err_ptrauth_repeated_authentication_option
+    : Error<"repeated '__ptrauth' authentication 
%select{mode|option}0%select{, prior "
+            "mode was '%2'| '%1'}0">;
+def err_ptrauth_option_missing_comma
+    : Error<"missing comma after '%0' option in '__ptrauth' qualifier">;
+
 /// main()
 // static main() is not an error in C, just in C++.
 def warn_static_main : Warning<"'main' should not be declared static">,
diff --git a/clang/include/clang/Basic/LangOptions.h 
b/clang/include/clang/Basic/LangOptions.h
index 4fa2dcffc75b6..0d1d94d63d076 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -67,6 +67,17 @@ enum class PointerAuthenticationMode : unsigned {
   SignAndAuth
 };
 
+static constexpr llvm::StringLiteral PointerAuthenticationOptionStrip = 
"strip";
+static constexpr llvm::StringLiteral PointerAuthenticationOptionSignAndStrip =
+    "sign-and-strip";
+static constexpr llvm::StringLiteral PointerAuthenticationOptionSignAndAuth =
+    "sign-and-auth";
+static constexpr llvm::StringLiteral PointerAuthenticationOptionIsaPointer =
+    "isa-pointer";
+static constexpr llvm::StringLiteral
+    PointerAuthenticationOptionAuthenticatesNullValues =
+        "authenticates-null-values";
+
 /// Bitfields of LangOptions, split out from LangOptions in order to ensure 
that
 /// this large collection of bitfields is a trivial class type.
 class LangOptionsBase {
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index d2881d5ac518a..030168849c7e2 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2610,7 +2610,39 @@ void PointerAuthQualifier::print(raw_ostream &OS,
   OS << "__ptrauth(";
   OS << getKey();
   OS << "," << unsigned(isAddressDiscriminated()) << ","
-     << getExtraDiscriminator() << ")";
+     << getExtraDiscriminator();
+
+  bool HasAppendedOption = false;
+  auto AppendOption = [&](StringRef Option) {
+    OS << ",";
+    if (!HasAppendedOption)
+      OS << '"';
+    HasAppendedOption = true;
+    OS << Option;
+  };
+  switch (getAuthenticationMode()) {
+  case PointerAuthenticationMode::None:
+    llvm_unreachable("Mode is unauthenticated but claims to be present");
+    return;
+  case PointerAuthenticationMode::Strip:
+    AppendOption(PointerAuthenticationOptionStrip);
+    break;
+  case PointerAuthenticationMode::SignAndStrip:
+    AppendOption(PointerAuthenticationOptionSignAndStrip);
+    break;
+  case clang::PointerAuthenticationMode::SignAndAuth:
+    // Don't emit default auth
+    break;
+  }
+  if (isIsaPointer())
+    AppendOption(PointerAuthenticationOptionIsaPointer);
+  if (authenticatesNullValues())
+    AppendOption(PointerAuthenticationOptionAuthenticatesNullValues);
+
+  if (HasAppendedOption)
+    OS << '"';
+
+  OS << ")";
 }
 
 std::string Qualifiers::getAsString() const {
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp 
b/clang/lib/CodeGen/CGExprConstant.cpp
index 0eec4dba4824a..15ae2bf6f28c6 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -2129,6 +2129,13 @@ class ConstantLValueEmitter : public 
ConstStmtVisitor<ConstantLValueEmitter,
 
 }
 
+static bool shouldSignPointer(const PointerAuthQualifier &PointerAuth) {
+  PointerAuthenticationMode AuthenticationMode =
+      PointerAuth.getAuthenticationMode();
+  return AuthenticationMode == PointerAuthenticationMode::SignAndStrip ||
+         AuthenticationMode == PointerAuthenticationMode::SignAndAuth;
+}
+
 llvm::Constant *ConstantLValueEmitter::tryEmit() {
   const APValue::LValueBase &base = Value.getLValueBase();
 
@@ -2162,7 +2169,8 @@ llvm::Constant *ConstantLValueEmitter::tryEmit() {
 
   // Apply pointer-auth signing from the destination type.
   if (PointerAuthQualifier PointerAuth = DestType.getPointerAuth();
-      PointerAuth && !result.HasDestPointerAuth) {
+      PointerAuth && !result.HasDestPointerAuth &&
+      shouldSignPointer(PointerAuth)) {
     value = Emitter.tryEmitConstantSignedPointer(value, PointerAuth);
     if (!value)
       return nullptr;
@@ -2210,8 +2218,9 @@ ConstantLValueEmitter::tryEmitBase(const 
APValue::LValueBase &base) {
     if (D->hasAttr<WeakRefAttr>())
       return CGM.GetWeakRefReference(D).getPointer();
 
-    auto PtrAuthSign = [&](llvm::Constant *C) {
-      if (PointerAuthQualifier PointerAuth = DestType.getPointerAuth()) {
+    auto PtrAuthSign = [&](llvm::Constant *C, bool IsFunction) {
+      if (PointerAuthQualifier PointerAuth = DestType.getPointerAuth();
+          PointerAuth && shouldSignPointer(PointerAuth)) {
         C = applyOffset(C);
         C = Emitter.tryEmitConstantSignedPointer(C, PointerAuth);
         return ConstantLValue(C, /*applied offset*/ true, /*signed*/ true);
@@ -2219,7 +2228,7 @@ ConstantLValueEmitter::tryEmitBase(const 
APValue::LValueBase &base) {
 
       CGPointerAuthInfo AuthInfo;
 
-      if (EnablePtrAuthFunctionTypeDiscrimination)
+      if (IsFunction && EnablePtrAuthFunctionTypeDiscrimination)
         AuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
 
       if (AuthInfo) {
@@ -2240,18 +2249,19 @@ ConstantLValueEmitter::tryEmitBase(const 
APValue::LValueBase &base) {
       llvm::Constant *C = CGM.getRawFunctionPointer(FD);
       if (FD->getType()->isCFIUncheckedCalleeFunctionType())
         C = llvm::NoCFIValue::get(cast<llvm::GlobalValue>(C));
-      return PtrAuthSign(C);
+      return PtrAuthSign(C, /*IsFunction=*/true);
     }
 
     if (const auto *VD = dyn_cast<VarDecl>(D)) {
       // We can never refer to a variable with local storage.
       if (!VD->hasLocalStorage()) {
         if (VD->isFileVarDecl() || VD->hasExternalStorage())
-          return CGM.GetAddrOfGlobalVar(VD);
+          return PtrAuthSign(CGM.GetAddrOfGlobalVar(VD), /*IsFunction=*/false);
 
         if (VD->isLocalVarDecl()) {
-          return CGM.getOrCreateStaticVarDecl(
+          llvm::Constant *C = CGM.getOrCreateStaticVarDecl(
               *VD, CGM.getLLVMLinkageVarDefinition(VD));
+          return PtrAuthSign(C, /*IsFunction=*/false);
         }
       }
     }
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 8688ccf41acb5..270c039dc6f40 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3172,7 +3172,7 @@ void Parser::ParsePtrauthQualifier(ParsedAttributes 
&Attrs) {
   T.consumeClose();
   SourceLocation EndLoc = T.getCloseLocation();
 
-  if (ArgExprs.empty() || ArgExprs.size() > 3) {
+  if (ArgExprs.empty() || ArgExprs.size() > 4) {
     Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
     return;
   }
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index fd64d4456cbfa..880a30ea55b54 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8456,14 +8456,15 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, 
const ParsedAttr &Attr,
 /// Handle the __ptrauth qualifier.
 static void HandlePtrAuthQualifier(ASTContext &Ctx, QualType &T,
                                    const ParsedAttr &Attr, Sema &S) {
-
-  assert((Attr.getNumArgs() > 0 && Attr.getNumArgs() <= 3) &&
-         "__ptrauth qualifier takes between 1 and 3 arguments");
+  assert((Attr.getNumArgs() > 0 && Attr.getNumArgs() <= 4) &&
+         "__ptrauth qualifier takes between 1 and 4 arguments");
   Expr *KeyArg = Attr.getArgAsExpr(0);
   Expr *IsAddressDiscriminatedArg =
       Attr.getNumArgs() >= 2 ? Attr.getArgAsExpr(1) : nullptr;
   Expr *ExtraDiscriminatorArg =
       Attr.getNumArgs() >= 3 ? Attr.getArgAsExpr(2) : nullptr;
+  Expr *AuthenticationOptionsArg =
+      Attr.getNumArgs() >= 4 ? Attr.getArgAsExpr(3) : nullptr;
 
   unsigned Key;
   if (S.checkConstantPointerAuthKey(KeyArg, Key)) {
@@ -8479,10 +8480,138 @@ static void HandlePtrAuthQualifier(ASTContext &Ctx, 
QualType &T,
                                                    IsAddressDiscriminated);
   IsInvalid |= !S.checkPointerAuthDiscriminatorArg(
       ExtraDiscriminatorArg, PointerAuthDiscArgKind::Extra, 
ExtraDiscriminator);
+  std::string LastAuthenticationMode;
+  std::optional<PointerAuthenticationMode> AuthenticationMode = std::nullopt;
+  bool IsIsaPointer = false;
+  bool AuthenticatesNullValues = false;
+
+  if (AuthenticationOptionsArg && !AuthenticationOptionsArg->containsErrors()) 
{
+    StringRef OptionsString;
+    std::string EvaluatedString;
+    bool HasEvaluatedOptionsString = false;
+    const StringLiteral *OptionsStringLiteral =
+        dyn_cast<StringLiteral>(AuthenticationOptionsArg);
+    SourceRange AuthenticationOptionsRange =
+        AuthenticationOptionsArg->getSourceRange();
+    bool ReportedEvaluation = false;
+    auto ReportEvaluationOfExpressionIfNeeded = [&]() {
+      if (OptionsStringLiteral || !HasEvaluatedOptionsString ||
+          ReportedEvaluation)
+        return;
+      ReportedEvaluation = true;
+      S.Diag(AuthenticationOptionsRange.getBegin(),
+             diag::note_ptrauth_evaluating_options)
+          << OptionsString << AuthenticationOptionsRange;
+    };
+    auto DiagnoseInvalidOptionsParameter = [&](llvm::StringRef Reason) {
+      S.Diag(AuthenticationOptionsRange.getBegin(),
+             diag::err_ptrauth_invalid_option)
+          << Reason;
+      Attr.setInvalid();
+      IsInvalid = true;
+      ReportEvaluationOfExpressionIfNeeded();
+    };
+    if (AuthenticationOptionsArg->isValueDependent() ||
+        AuthenticationOptionsArg->isTypeDependent()) {
+      DiagnoseInvalidOptionsParameter("is dependent");
+      return;
+    }
+    if (OptionsStringLiteral) {
+      OptionsString = OptionsStringLiteral->getString();
+      HasEvaluatedOptionsString = true;
+    } else {
+      Expr::EvalResult Eval;
+      bool Result = AuthenticationOptionsArg->EvaluateAsRValue(Eval, Ctx);
+      if (Result && Eval.Val.isLValue()) {
+        auto *BaseExpr = Eval.Val.getLValueBase().dyn_cast<const Expr *>();
+        const StringLiteral *EvaluatedStringLiteral =
+            dyn_cast<StringLiteral>(const_cast<Expr *>(BaseExpr));
+        if (EvaluatedStringLiteral) {
+          CharUnits StartOffset = Eval.Val.getLValueOffset();
+          EvaluatedString = EvaluatedStringLiteral->getString().drop_front(
+              StartOffset.getQuantity());
+          OptionsString = EvaluatedString;
+          HasEvaluatedOptionsString = true;
+        }
+      }
+    }
+    if (!HasEvaluatedOptionsString) {
+      DiagnoseInvalidOptionsParameter(
+          "must be a string of comma separated flags");
+      return;
+    }
+    for (char Ch : OptionsString) {
+      if (Ch != '-' && Ch != ',' && !isWhitespace(Ch) && !isalpha(Ch)) {
+        DiagnoseInvalidOptionsParameter("contains invalid characters");
+        return;
+      }
+    }
+    HasEvaluatedOptionsString = true;
+    OptionsString = OptionsString.trim();
+    llvm::SmallVector<StringRef> Options;
+    if (!OptionsString.empty())
+      OptionsString.split(Options, ',');
+
+    auto OptionHandler = [&](auto Value, auto *Option,
+                             std::string *LastOption = nullptr) {
+      return [&, Value, Option, LastOption](StringRef OptionString) {
+        if (!*Option) {
+          *Option = Value;
+          if (LastOption)
+            *LastOption = OptionString;
+          return true;
+        }
+        bool IsAuthenticationMode =
+            std::is_same_v<decltype(Value), PointerAuthenticationMode>;
+        S.Diag(AuthenticationOptionsRange.getBegin(),
+               diag::err_ptrauth_repeated_authentication_option)
+            << !IsAuthenticationMode << OptionString
+            << (LastOption ? *LastOption : "");
+        return false;
+      };
+    };
 
-  if (IsInvalid) {
-    Attr.setInvalid();
-    return;
+    for (unsigned Idx = 0; Idx < Options.size(); ++Idx) {
+      StringRef Option = Options[Idx].trim();
+      if (Option.empty()) {
+        bool IsLastOption = Idx == (Options.size() - 1);
+        DiagnoseInvalidOptionsParameter(
+            IsLastOption ? "has a trailing comma" : "contains an empty 
option");
+        continue;
+      }
+      auto SelectedHandler =
+          llvm::StringSwitch<std::function<bool(StringRef)>>(Option)
+              .Case(PointerAuthenticationOptionStrip,
+                    OptionHandler(PointerAuthenticationMode::Strip,
+                                  &AuthenticationMode, 
&LastAuthenticationMode))
+              .Case(PointerAuthenticationOptionSignAndStrip,
+                    OptionHandler(PointerAuthenticationMode::SignAndStrip,
+                                  &AuthenticationMode, 
&LastAuthenticationMode))
+              .Case(PointerAuthenticationOptionSignAndAuth,
+                    OptionHandler(PointerAuthenticationMode::SignAndAuth,
+                                  &AuthenticationMode, 
&LastAuthenticationMode))
+              .Case(PointerAuthenticationOptionIsaPointer,
+                    OptionHandler(true, &IsIsaPointer))
+              .Case(PointerAuthenticationOptionAuthenticatesNullValues,
+                    OptionHandler(true, &AuthenticatesNullValues))
+              .Default([&](StringRef Option) {
+                if (size_t WhitespaceIndex =
+                        Option.find_first_of(" \t\n\v\f\r");
+                    WhitespaceIndex != Option.npos) {
+                  StringRef LeadingOption = Option.slice(0, WhitespaceIndex);
+                  S.Diag(AuthenticationOptionsRange.getBegin(),
+                         diag::err_ptrauth_option_missing_comma)
+                      << LeadingOption;
+                } else {
+                  S.Diag(AuthenticationOptionsRange.getBegin(),
+                         diag::err_ptrauth_unknown_authentication_option)
+                      << Option;
+                }
+                return false;
+              });
+      if (!SelectedHandler(Option))
+        IsInvalid = true;
+    }
   }
 
   if (!T->isSignableType(Ctx) && !T->isDependentType()) {
@@ -8491,6 +8620,9 @@ static void HandlePtrAuthQualifier(ASTContext &Ctx, 
QualType &T,
     return;
   }
 
+  if (!AuthenticationMode)
+    AuthenticationMode = PointerAuthenticationMode::SignAndAuth;
+
   if (T.getPointerAuth()) {
     S.Diag(Attr.getLoc(), diag::err_ptrauth_qualifier_redundant) << T;
     Attr.setInvalid();
@@ -8503,13 +8635,19 @@ static void HandlePtrAuthQualifier(ASTContext &Ctx, 
QualType &T,
     return;
   }
 
+  if (IsInvalid) {
+    Attr.setInvalid();
+    return;
+  }
+
   assert((!IsAddressDiscriminatedArg || IsAddressDiscriminated <= 1) &&
          "address discriminator arg should be either 0 or 1");
   PointerAuthQualifier Qual = PointerAuthQualifier::Create(
-      Key, IsAddressDiscriminated, ExtraDiscriminator,
-      PointerAuthenticationMode::SignAndAuth, /*IsIsaPointer=*/false,
-      /*AuthenticatesNullValues=*/false);
+      Key, IsAddressDiscriminated, ExtraDiscriminator, *AuthenticationMode,
+      IsIsaPointer, AuthenticatesNullValues);
+  assert(Qual.getAuthenticationMode() == *AuthenticationMode);
   T = S.Context.getPointerAuthType(T, Qual);
+  assert(T.getPointerAuth().getAuthenticationMode() == *AuthenticationMode);
 }
 
 /// HandleArmSveVectorBitsTypeAttr - The "arm_sve_vector_bits...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/172187
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to