[clang] [lldb] [clang] Add `__ptrauth_restricted_intptr` qualifier (PR #137580)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 27 22:37:48 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-clang
Author: Oliver Hunt (ojhunt)
<details>
<summary>Changes</summary>
__ptrauth_restricted_intptr provides a mechanism to apply pointer authentication to pointer sized integer types.
---
Patch is 49.31 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137580.diff
26 Files Affected:
- (modified) clang/docs/PointerAuthentication.rst (+14)
- (modified) clang/docs/ReleaseNotes.rst (+1-1)
- (modified) clang/include/clang/AST/Type.h (+35-17)
- (modified) clang/include/clang/Basic/Attr.td (+2-1)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+19-12)
- (modified) clang/include/clang/Basic/Features.def (+1)
- (modified) clang/include/clang/Basic/TokenKinds.def (+1)
- (modified) clang/include/clang/Sema/Sema.h (+2-1)
- (modified) clang/lib/AST/ASTContext.cpp (+3)
- (modified) clang/lib/AST/Type.cpp (+6)
- (modified) clang/lib/AST/TypePrinter.cpp (+4-1)
- (modified) clang/lib/CodeGen/CGExprConstant.cpp (+3)
- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+1-1)
- (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+13-9)
- (modified) clang/lib/Parse/ParseDecl.cpp (+7-2)
- (modified) clang/lib/Sema/SemaCast.cpp (+1-1)
- (modified) clang/lib/Sema/SemaChecking.cpp (+7-4)
- (modified) clang/lib/Sema/SemaDecl.cpp (+2-1)
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+1-1)
- (modified) clang/lib/Sema/SemaObjCProperty.cpp (+3-3)
- (modified) clang/lib/Sema/SemaType.cpp (+29-14)
- (modified) clang/lib/Sema/TreeTransform.h (+17-4)
- (added) clang/test/CodeGen/ptrauth-restricted-intptr-qualifier.c (+220)
- (added) clang/test/Sema/ptrauth-restricted-intptr-qualifier.c (+45)
- (modified) clang/test/SemaCXX/ptrauth-triviality.cpp (+44)
- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+6-1)
``````````diff
diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst
index 41818d43ac687..2278971d757c9 100644
--- a/clang/docs/PointerAuthentication.rst
+++ b/clang/docs/PointerAuthentication.rst
@@ -326,6 +326,20 @@ a discriminator determined as follows:
is ``ptrauth_blend_discriminator(&x, discriminator)``; see
`ptrauth_blend_discriminator`_.
+__ptrauth_restricted_intptr qualifier
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+This is a variant of the ``__ptrauth`` qualifier, that applies to pointer sized
+integers. See the documentation for ``__ptrauth qualifier``.
+
+This feature exists to support older APIs that use [u]intptrs to hold opaque
+pointer types.
+
+Care must be taken to avoid using the signature bit components of the signed
+integers or subsequent authentication of the signed value may fail.
+
+Note: When applied to a global initialiser a signed uintptr can only be
+initialised with the value 0 or a global address.
+
``<ptrauth.h>``
~~~~~~~~~~~~~~~
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index eb2e8f2b8a6c0..fe9badf7ba97a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -608,7 +608,7 @@ Arm and AArch64 Support
ARM targets, however this will now disable NEON instructions being generated. The ``simd`` option is
also now printed when the ``--print-supported-extensions`` option is used.
-- Support for __ptrauth type qualifier has been added.
+- Support for __ptrauth and __ptrauth_restricted_intptr type qualifiers has been added.
- For AArch64, added support for generating executable-only code sections by using the
``-mexecute-only`` or ``-mpure-code`` compiler flags. (#GH125688)
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 3e1fb05ad537c..6516c976e66c5 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -168,8 +168,13 @@ class PointerAuthQualifier {
AuthenticatesNullValuesBits = 1,
AuthenticatesNullValuesMask = ((1 << AuthenticatesNullValuesBits) - 1)
<< AuthenticatesNullValuesShift,
- KeyShift = AuthenticatesNullValuesShift + AuthenticatesNullValuesBits,
- KeyBits = 10,
+ RestrictedIntegralShift =
+ AuthenticatesNullValuesShift + AuthenticatesNullValuesBits,
+ RestrictedIntegralBits = 1,
+ RestrictedIntegralMask = ((1 << RestrictedIntegralBits) - 1)
+ << RestrictedIntegralShift,
+ KeyShift = RestrictedIntegralShift + RestrictedIntegralBits,
+ KeyBits = 9,
KeyMask = ((1 << KeyBits) - 1) << KeyShift,
DiscriminatorShift = KeyShift + KeyBits,
DiscriminatorBits = 16,
@@ -178,32 +183,33 @@ class PointerAuthQualifier {
// bits: |0 |1 |2..3 |4 |
// |Enabled|Address|AuthenticationMode|ISA pointer|
- // bits: |5 |6..15| 16...31 |
- // |AuthenticatesNull|Key |Discriminator|
+ // bits: |5 |6 |7..15| 16...31 |
+ // |AuthenticatesNull|RestrictedIntegral|Key |Discriminator|
uint32_t Data = 0;
// The following static assertions check that each of the 32 bits is present
// exactly in one of the constants.
static_assert((EnabledBits + AddressDiscriminatedBits +
AuthenticationModeBits + IsaPointerBits +
- AuthenticatesNullValuesBits + KeyBits + DiscriminatorBits) ==
- 32,
+ AuthenticatesNullValuesBits + RestrictedIntegralBits +
+ KeyBits + DiscriminatorBits) == 32,
"PointerAuthQualifier should be exactly 32 bits");
static_assert((EnabledMask + AddressDiscriminatedMask +
AuthenticationModeMask + IsaPointerMask +
- AuthenticatesNullValuesMask + KeyMask + DiscriminatorMask) ==
- 0xFFFFFFFF,
+ AuthenticatesNullValuesMask + RestrictedIntegralMask +
+ KeyMask + DiscriminatorMask) == 0xFFFFFFFF,
"All masks should cover the entire bits");
static_assert((EnabledMask ^ AddressDiscriminatedMask ^
AuthenticationModeMask ^ IsaPointerMask ^
- AuthenticatesNullValuesMask ^ KeyMask ^ DiscriminatorMask) ==
- 0xFFFFFFFF,
+ AuthenticatesNullValuesMask ^ RestrictedIntegralMask ^
+ KeyMask ^ DiscriminatorMask) == 0xFFFFFFFF,
"All masks should cover the entire bits");
PointerAuthQualifier(unsigned Key, bool IsAddressDiscriminated,
unsigned ExtraDiscriminator,
PointerAuthenticationMode AuthenticationMode,
- bool IsIsaPointer, bool AuthenticatesNullValues)
+ bool IsIsaPointer, bool AuthenticatesNullValues,
+ bool IsRestrictedIntegral)
: Data(EnabledMask |
(IsAddressDiscriminated
? llvm::to_underlying(AddressDiscriminatedMask)
@@ -212,8 +218,8 @@ class PointerAuthQualifier {
(llvm::to_underlying(AuthenticationMode)
<< AuthenticationModeShift) |
(ExtraDiscriminator << DiscriminatorShift) |
- (IsIsaPointer << IsaPointerShift) |
- (AuthenticatesNullValues << AuthenticatesNullValuesShift)) {
+ (AuthenticatesNullValues << AuthenticatesNullValuesShift) |
+ (IsRestrictedIntegral << RestrictedIntegralShift)) {
assert(Key <= KeyNoneInternal);
assert(ExtraDiscriminator <= MaxDiscriminator);
assert((Data == 0) ==
@@ -237,13 +243,13 @@ class PointerAuthQualifier {
static PointerAuthQualifier
Create(unsigned Key, bool IsAddressDiscriminated, unsigned ExtraDiscriminator,
PointerAuthenticationMode AuthenticationMode, bool IsIsaPointer,
- bool AuthenticatesNullValues) {
+ bool AuthenticatesNullValues, bool IsRestrictedIntegral) {
if (Key == PointerAuthKeyNone)
Key = KeyNoneInternal;
assert(Key <= KeyNoneInternal && "out-of-range key value");
return PointerAuthQualifier(Key, IsAddressDiscriminated, ExtraDiscriminator,
AuthenticationMode, IsIsaPointer,
- AuthenticatesNullValues);
+ AuthenticatesNullValues, IsRestrictedIntegral);
}
bool isPresent() const {
@@ -290,6 +296,10 @@ class PointerAuthQualifier {
return hasKeyNone() ? PointerAuthQualifier() : *this;
}
+ bool isRestrictedIntegral() const {
+ return (Data & RestrictedIntegralMask) >> RestrictedIntegralShift;
+ }
+
friend bool operator==(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) {
return Lhs.Data == Rhs.Data;
}
@@ -2563,7 +2573,9 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
bool isPointerType() const;
bool isPointerOrReferenceType() const;
- bool isSignableType() const;
+ bool isSignableType(const ASTContext &Ctx) const;
+ bool isSignablePointerType() const;
+ bool isSignableIntegerType(const ASTContext &Ctx) const;
bool isAnyPointerType() const; // Any C pointer or ObjC object pointer
bool isCountAttributedType() const;
bool isBlockPointerType() const;
@@ -8216,7 +8228,13 @@ inline bool Type::isAnyPointerType() const {
return isPointerType() || isObjCObjectPointerType();
}
-inline bool Type::isSignableType() const { return isPointerType(); }
+inline bool Type::isSignableType(const ASTContext &Ctx) const {
+ return isSignablePointerType() || isSignableIntegerType(Ctx);
+}
+
+inline bool Type::isSignablePointerType() const {
+ return isPointerType() || isObjCClassType() || isObjCQualifiedClassType();
+}
inline bool Type::isBlockPointerType() const {
return isa<BlockPointerType>(CanonicalType);
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index dcdcff8c46fe2..50bfe76a86619 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3578,7 +3578,8 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
}
def PointerAuth : TypeAttr {
- let Spellings = [CustomKeyword<"__ptrauth">];
+ let Spellings = [CustomKeyword<"__ptrauth">,
+ CustomKeyword<"__ptrauth_restricted_intptr">];
let Args = [IntArgument<"Key">,
BoolArgument<"AddressDiscriminated", 1>,
IntArgument<"ExtraDiscriminator", 1>];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4c96142e28134..79e26ff9293f0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1021,20 +1021,27 @@ def err_ptrauth_indirect_goto_addrlabel_arithmetic : Error<
"supported with ptrauth indirect gotos">;
// __ptrauth qualifier
-def err_ptrauth_qualifier_invalid : Error<
- "%select{return type|parameter type|property}1 may not be qualified with '__ptrauth'; type is %0">;
-def err_ptrauth_qualifier_cast : Error<
- "cannot cast to '__ptrauth'-qualified type %0">;
-def err_ptrauth_qualifier_nonpointer : Error<
- "'__ptrauth' qualifier only applies to pointer types; %0 is invalid">;
+def err_ptrauth_qualifier_invalid
+ : Error<
+ "%select{return type|parameter type|property}0 may not be qualified "
+ "with '%select{__ptrauth_restricted_intptr|__ptrauth}1'; type is %2">;
+def err_ptrauth_qualifier_cast : Error<"cannot cast to "
+ "'%select{__ptrauth_restricted_intptr|__"
+ "ptrauth}0'-qualified type %1">;
+def err_ptrauth_qualifier_invalid_target
+ : Error<"'%select{__ptrauth_restricted_intptr|__ptrauth}0' qualifier only "
+ "applies to %select{pointer sized integer|pointer}0 types; %1 is "
+ "invalid">;
def err_ptrauth_qualifier_redundant : Error<
"type %0 is already %1-qualified">;
-def err_ptrauth_arg_not_ice : Error<
- "argument to '__ptrauth' must be an integer constant expression">;
-def err_ptrauth_address_discrimination_invalid : Error<
- "invalid address discrimination flag '%0'; '__ptrauth' requires '0' or '1'">;
-def err_ptrauth_extra_discriminator_invalid : Error<
- "invalid extra discriminator flag '%0'; '__ptrauth' requires a value between '0' and '%1'">;
+def err_ptrauth_arg_not_ice
+ : Error<"argument to '%0' must be an integer constant expression">;
+def err_ptrauth_address_discrimination_invalid
+ : Error<
+ "invalid address discrimination flag '%0'; '%1' requires '0' or '1'">;
+def err_ptrauth_extra_discriminator_invalid
+ : Error<"invalid extra discriminator flag '%0'; '%1' requires a value "
+ "between '0' and '%2'">;
/// main()
// static main() is not an error in C, just in C++.
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index 14bff8a68846d..c859167e47e57 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -108,6 +108,7 @@ FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics)
EXTENSION(ptrauth_qualifier, LangOpts.PointerAuthIntrinsics)
+EXTENSION(ptrauth_restricted_intptr_qualifier, LangOpts.PointerAuthIntrinsics)
FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls)
FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns)
FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination)
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 868e851342eb8..85c0f58181c98 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -349,6 +349,7 @@ KEYWORD(__func__ , KEYALL)
KEYWORD(__objc_yes , KEYALL)
KEYWORD(__objc_no , KEYALL)
KEYWORD(__ptrauth , KEYALL)
+KEYWORD(__ptrauth_restricted_intptr , KEYALL)
// C2y
UNARY_EXPR_OR_TYPE_TRAIT(_Countof, CountOf, KEYNOCXX)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0c77c5b5ca30a..e438194230cf7 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3599,7 +3599,8 @@ class Sema final : public SemaBase {
PADAK_ExtraDiscPtrAuth,
};
- bool checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind,
+ bool checkPointerAuthDiscriminatorArg(const AttributeCommonInfo &AttrInfo,
+ Expr *Arg, PointerAuthDiscArgKind Kind,
unsigned &IntVal);
/// Diagnose function specifiers on a declaration of an identifier that
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index c95e733f30494..73051f46444f8 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2924,6 +2924,9 @@ bool ASTContext::hasUniqueObjectRepresentations(
// All integrals and enums are unique.
if (Ty->isIntegralOrEnumerationType()) {
+ // Address discriminated __ptrauth_restricted_intptr types are not unique
+ if (Ty.hasAddressDiscriminatedPointerAuth())
+ return false;
// Except _BitInt types that have padding bits.
if (const auto *BIT = Ty->getAs<BitIntType>())
return getTypeSize(BIT) == BIT->getNumBits();
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 111a642173418..4bf4a02d47fbd 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -5056,6 +5056,12 @@ AttributedType::stripOuterNullability(QualType &T) {
return std::nullopt;
}
+bool Type::isSignableIntegerType(const ASTContext &Ctx) const {
+ if (!isIntegralType(Ctx) || isEnumeralType())
+ return false;
+ return Ctx.getTypeSize(this) == Ctx.getTypeSize(Ctx.VoidPtrTy);
+}
+
bool Type::isBlockCompatibleObjCPointerType(ASTContext &ctx) const {
const auto *objcPtr = getAs<ObjCObjectPointerType>();
if (!objcPtr)
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index cba1a2d98d660..fe4283abc7017 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2534,7 +2534,10 @@ void PointerAuthQualifier::print(raw_ostream &OS,
if (!isPresent())
return;
- OS << "__ptrauth(";
+ if (isRestrictedIntegral())
+ OS << "__ptrauth_restricted_intptr(";
+ else
+ OS << "__ptrauth(";
OS << getKey();
OS << "," << unsigned(isAddressDiscriminated()) << ","
<< getExtraDiscriminator() << ")";
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index b21ebeee4bed1..d196e39ea374c 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -2444,6 +2444,9 @@ ConstantEmitter::tryEmitPrivate(const APValue &Value, QualType DestType,
EnablePtrAuthFunctionTypeDiscrimination)
.tryEmit();
case APValue::Int:
+ if (PointerAuthQualifier PointerAuth = DestType.getPointerAuth();
+ PointerAuth && (PointerAuth.authenticatesNullValues() || Value.getInt() != 0))
+ return nullptr;
return llvm::ConstantInt::get(CGM.getLLVMContext(), Value.getInt());
case APValue::FixedPoint:
return llvm::ConstantInt::get(CGM.getLLVMContext(),
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 8dbbcdaef25d8..ff84e3c3f87e9 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2287,7 +2287,7 @@ static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E) {
}
bool CodeGenFunction::isPointerKnownNonNull(const Expr *E) {
- assert(E->getType()->isSignableType());
+ assert(E->getType()->isSignableType(getContext()));
E = E->IgnoreParens();
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp
index 0a183a8524c17..01f43630edce3 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -175,7 +175,7 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForPointeeType(QualType T) {
/// pointer type.
static CGPointerAuthInfo getPointerAuthInfoForType(CodeGenModule &CGM,
QualType PointerType) {
- assert(PointerType->isSignableType());
+ assert(PointerType->isSignableType(CGM.getContext()));
// Block pointers are currently not signed.
if (PointerType->isBlockPointerType())
@@ -209,7 +209,7 @@ emitLoadOfOrigPointerRValue(CodeGenFunction &CGF, const LValue &LV,
/// needlessly resigning the pointer.
std::pair<llvm::Value *, CGPointerAuthInfo>
CodeGenFunction::EmitOrigPointerRValue(const Expr *E) {
- assert(E->getType()->isSignableType());
+ assert(E->getType()->isSignableType(getContext()));
E = E->IgnoreParens();
if (const auto *Load = dyn_cast<ImplicitCastExpr>(E)) {
@@ -291,7 +291,10 @@ static bool equalAuthPolicies(const CGPointerAuthInfo &Left,
if (Left.isSigned() != Right.isSigned())
return false;
return Left.getKey() == Right.getKey() &&
- Left.getAuthenticationMode() == Right.getAuthenticationMode();
+ Left.getAuthenticationMode() == Right.getAuthenticationMode() &&
+ Left.isIsaPointer() == Right.isIsaPointer() &&
+ Left.authenticatesNullValues() == Right.authenticatesNullValues() &&
+ Left.getDiscriminator() == Right.getDiscriminator();
}
// Return the discriminator or return zero if the discriminator is null.
@@ -590,8 +593,9 @@ CodeGenModule::computeVTPointerAuthentication(const CXXRecordDecl *ThisClass) {
}
return PointerAuthQualifier::Create(Key, AddressDiscriminated, Discriminator,
PointerAuthenticationMode::SignAndAuth,
- /* IsIsaPointer */ false,
- /* AuthenticatesNullValues */ false);
+ /*IsIsaPointer=*/false,
+ /*AuthenticatesNullValues=*/false,
+ /*IsRestrictedIntegral=*/false);
}
std::optional<PointerAuthQualifier>
@@ -642,10 +646,10 @@ llvm::Value *CodeGenFunction::authPointerToPointerCast(llvm::Value *ResultPtr,
QualType SourceType,
QualType DestType) {
CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
- if (SourceType->isSignableType())
+ if (SourceType->isSignableType(getContext()))
CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
- if (DestType->isSignableType())
+ if (DestType->isSignableType(getContext()))
NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
if (!CurAuthInfo && !NewAuthInfo)
@@ -667,10 +671,10 @@ Address CodeGenFunction::authPointerToPointerCast(Address Ptr,
QualType SourceType,
QualType DestType) {
CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
- if (SourceType->isSignableType())
+ if (SourceType->isSignableType(getContext()))
CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
- if (DestType->isSignableType())
+ if (DestType->isSignableType(getContext()))
NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
if (!CurAuthInfo && !NewAuthInfo)
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 69d40baaf4298..4db4c8670cc31 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3401,11 +3401,12 @@ void Parser::DistributeCLateParsedAttrs(Decl *Dcl,
}
/// type-qualifier:
-/// ('__ptrauth') '(' constant-expression
+/// ('__ptrauth' | '__ptrauth_restricted_intptr') '(' constant-expression
/// (',' constant-expression)[opt]
/// (',' constant-expression)[opt] ')'
void Parser::ParsePtrauthQualifier(ParsedAttributes &Attrs) {
- assert(Tok.is(tok::kw___ptrauth));
+ assert(Tok.is(tok::kw___ptrauth) ||
+ Tok.is(tok::kw___ptrauth_restricted_intptr));
IdentifierInfo *KwName = Tok.getIdentifierInfo();
SourceLo...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/137580
More information about the cfe-commits
mailing list