Skip to content

Commit 3311e15

Browse files
ojhuntGeorgeARM
authored andcommitted
[clang][ptrauth] reject incorrectly placed ptrauth qualifier (llvm#138376)
When parsing a function pointer typed field we use Parser::ParseTypeQualifierListOpt, but then drops subsequent type attributes and qualifiers unless explicitly handled. There is an existing solution for the _Atomic qualifier, and this PR simply extends that to __ptrauth for now. In future we may want to investigate a more robust mechanism to ensure type qualifiers are not silently dropped so that future type qualifiers do not suffer the same problem.
1 parent 299b990 commit 3311e15

File tree

4 files changed

+16
-6
lines changed

4 files changed

+16
-6
lines changed

clang/include/clang/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3253,7 +3253,7 @@ class Parser : public CodeCompletionHandler {
32533253

32543254
void ParseTypeQualifierListOpt(
32553255
DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
3256-
bool AtomicAllowed = true, bool IdentifierRequired = false,
3256+
bool AtomicOrPtrauthAllowed = true, bool IdentifierRequired = false,
32573257
std::optional<llvm::function_ref<void()>> CodeCompletionHandler =
32583258
std::nullopt);
32593259
void ParseDirectDeclarator(Declarator &D);

clang/lib/Parse/ParseDecl.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6511,7 +6511,7 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
65116511
/// Note: vendor can be GNU, MS, etc and can be explicitly controlled via
65126512
/// AttrRequirements bitmask values.
65136513
void Parser::ParseTypeQualifierListOpt(
6514-
DeclSpec &DS, unsigned AttrReqs, bool AtomicAllowed,
6514+
DeclSpec &DS, unsigned AttrReqs, bool AtomicOrPtrauthAllowed,
65156515
bool IdentifierRequired,
65166516
std::optional<llvm::function_ref<void()>> CodeCompletionHandler) {
65176517
if ((AttrReqs & AR_CXX11AttributesParsed) &&
@@ -6551,7 +6551,7 @@ void Parser::ParseTypeQualifierListOpt(
65516551
getLangOpts());
65526552
break;
65536553
case tok::kw__Atomic:
6554-
if (!AtomicAllowed)
6554+
if (!AtomicOrPtrauthAllowed)
65556555
goto DoneWithTypeQuals;
65566556
diagnoseUseOfC11Keyword(Tok);
65576557
isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,
@@ -6584,6 +6584,8 @@ void Parser::ParseTypeQualifierListOpt(
65846584

65856585
// __ptrauth qualifier.
65866586
case tok::kw___ptrauth:
6587+
if (!AtomicOrPtrauthAllowed)
6588+
goto DoneWithTypeQuals;
65876589
ParsePtrauthQualifier(DS.getAttributes());
65886590
EndLoc = PrevTokLocation;
65896591
continue;
@@ -6860,7 +6862,8 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
68606862
((D.getContext() != DeclaratorContext::CXXNew)
68616863
? AR_GNUAttributesParsed
68626864
: AR_GNUAttributesParsedAndRejected);
6863-
ParseTypeQualifierListOpt(DS, Reqs, true, !D.mayOmitIdentifier());
6865+
ParseTypeQualifierListOpt(DS, Reqs, /*AtomicOrPtrauthAllowed=*/true,
6866+
!D.mayOmitIdentifier());
68646867
D.ExtendWithDeclSpec(DS);
68656868

68666869
// Recursively parse the declarator.
@@ -7725,7 +7728,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
77257728
// Parse cv-qualifier-seq[opt].
77267729
ParseTypeQualifierListOpt(
77277730
DS, AR_NoAttributesParsed,
7728-
/*AtomicAllowed*/ false,
7731+
/*AtomicOrPtrauthAllowed=*/false,
77297732
/*IdentifierRequired=*/false, llvm::function_ref<void()>([&]() {
77307733
Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
77317734
}));

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2802,7 +2802,7 @@ void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
28022802
// GNU-style and C++11 attributes are not allowed here, but they will be
28032803
// handled by the caller. Diagnose everything else.
28042804
ParseTypeQualifierListOpt(
2805-
DS, AR_NoAttributesParsed, false,
2805+
DS, AR_NoAttributesParsed, /*AtomicOrPtrauthAllowed=*/false,
28062806
/*IdentifierRequired=*/false, llvm::function_ref<void()>([&]() {
28072807
Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D, &VS);
28082808
}));
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %clang_cc1 -triple arm64-apple-ios -x c -fsyntax-only -verify -fptrauth-intrinsics %s -fexperimental-new-constant-interpreter
2+
// RUN: %clang_cc1 -triple arm64-apple-ios -x c++ -fsyntax-only -verify -fptrauth-intrinsics %s -fexperimental-new-constant-interpreter
3+
4+
struct Foo {
5+
void (*f)(int) __ptrauth(1,1,1);
6+
// expected-error@-1 {{expected ';' at end of declaration list}}
7+
};

0 commit comments

Comments
 (0)