Skip to content

Commit 7de32ca

Browse files
committed
Make parsing of parentheses mandatory when an attribute keyword takes arguments [to squash]
1 parent 1decf81 commit 7de32ca

File tree

7 files changed

+30
-52
lines changed

7 files changed

+30
-52
lines changed

clang/include/clang/Basic/AttributeCommonInfo.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,10 @@ class AttributeCommonInfo {
256256
}
257257
};
258258

259-
enum class KeywordAttributeParseArgumentsKind { None, Optional, Required };
260-
261-
inline KeywordAttributeParseArgumentsKind
262-
getKeywordAttributeParseArgumentsKind(tok::TokenKind Kind) {
259+
inline bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind) {
263260
switch (Kind) {
264261
default:
265-
return KeywordAttributeParseArgumentsKind::None;
262+
return false;
266263
#define KEYWORD_ATTRIBUTE(NAME, HASARG) \
267264
case tok::kw_##NAME: \
268265
return HASARG;

clang/lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6786,9 +6786,9 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
67866786
} else if (Tok.isRegularKeywordAttribute()) {
67876787
// For consistency with attribute parsing.
67886788
Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6789-
auto ParseArgsKind = getKeywordAttributeParseArgumentsKind(Tok.getKind());
6789+
bool TakesArgs = doesKeywordAttributeTakeArgs(Tok.getKind());
67906790
ConsumeToken();
6791-
if (ParseArgsKind != KeywordAttributeParseArgumentsKind::None) {
6791+
if (TakesArgs) {
67926792
BalancedDelimiterTracker T(*this, tok::l_paren);
67936793
if (!T.consumeOpen())
67946794
T.skipToEnd();

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,10 +1890,9 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
18901890
if (!SkipUntil(tok::r_paren, StopAtSemi))
18911891
break;
18921892
} else if (Tok.isRegularKeywordAttribute()) {
1893-
auto ParseArgsKind =
1894-
getKeywordAttributeParseArgumentsKind(Tok.getKind());
1893+
bool TakesArgs = doesKeywordAttributeTakeArgs(Tok.getKind());
18951894
ConsumeToken();
1896-
if (ParseArgsKind != KeywordAttributeParseArgumentsKind::None) {
1895+
if (TakesArgs) {
18971896
BalancedDelimiterTracker T(*this, tok::l_paren);
18981897
if (!T.consumeOpen())
18991898
T.skipToEnd();
@@ -4545,18 +4544,16 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
45454544
SourceLocation Loc = Tok.getLocation();
45464545
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
45474546
ParsedAttr::Form Form = ParsedAttr::Form(Tok.getKind());
4548-
KeywordAttributeParseArgumentsKind ParseArgsKind =
4549-
getKeywordAttributeParseArgumentsKind(Tok.getKind());
4547+
bool TakesArgs = doesKeywordAttributeTakeArgs(Tok.getKind());
45504548
ConsumeToken();
4551-
if (ParseArgsKind == KeywordAttributeParseArgumentsKind::Required &&
4552-
!Tok.is(tok::l_paren))
4553-
Diag(Tok.getLocation(), diag::err_expected_lparen_after) << AttrName;
4554-
if (ParseArgsKind != KeywordAttributeParseArgumentsKind::None &&
4555-
Tok.is(tok::l_paren))
4556-
ParseAttributeArgsCommon(AttrName, Loc, Attrs, EndLoc,
4557-
/*ScopeName*/ nullptr,
4558-
/*ScopeLoc*/ Loc, Form);
4559-
else
4549+
if (TakesArgs) {
4550+
if (!Tok.is(tok::l_paren))
4551+
Diag(Tok.getLocation(), diag::err_expected_lparen_after) << AttrName;
4552+
else
4553+
ParseAttributeArgsCommon(AttrName, Loc, Attrs, EndLoc,
4554+
/*ScopeName*/ nullptr,
4555+
/*ScopeLoc*/ Loc, Form);
4556+
} else
45604557
Attrs.addNew(AttrName, Loc, nullptr, Loc, nullptr, 0, Form);
45614558
return;
45624559
}
@@ -4724,8 +4721,7 @@ SourceLocation Parser::SkipCXX11Attributes() {
47244721
T.skipToEnd();
47254722
EndLoc = T.getCloseLocation();
47264723
} else if (Tok.isRegularKeywordAttribute() &&
4727-
getKeywordAttributeParseArgumentsKind(Tok.getKind()) ==
4728-
KeywordAttributeParseArgumentsKind::None) {
4724+
!doesKeywordAttributeTakeArgs(Tok.getKind())) {
47294725
EndLoc = Tok.getLocation();
47304726
ConsumeToken();
47314727
} else {

clang/lib/Parse/ParseTentative.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -895,8 +895,7 @@ bool Parser::TrySkipAttributes() {
895895
// expected in the case of the Objective-C message send syntax.
896896
ConsumeBracket();
897897
} else if (Tok.isRegularKeywordAttribute() &&
898-
getKeywordAttributeParseArgumentsKind(Tok.getKind()) ==
899-
KeywordAttributeParseArgumentsKind::None) {
898+
!doesKeywordAttributeTakeArgs(Tok.getKind())) {
900899
ConsumeToken();
901900
} else {
902901
ConsumeToken();

clang/test/Parser/c2x-attribute-keywords.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,10 @@ void f11(void) {
117117
struct __arm_inout("za") S4 *s; // expected-error {{'__arm_inout' cannot appear here}}
118118
struct S5 {};
119119
int c = sizeof(struct __arm_inout("za") S5); // expected-error {{'__arm_inout' cannot appear here}}
120+
121+
void invalid_parentheses1() __arm_inout; // expected-error {{expected '(' after ''__arm_inout''}}
122+
void invalid_parentheses2() __arm_inout(; // expected-error {{expected string literal as argument of '__arm_inout' attribute}}
123+
void invalid_parentheses3() __arm_inout((); // expected-error {{expected string literal as argument of '__arm_inout' attribute}}
124+
void invalid_parentheses4() __arm_inout); // expected-error {{expected '(' after ''__arm_inout''}} \
125+
// expected-error {{expected function body after function declarator}}
126+
void invalid_parentheses5() __arm_inout(()); // expected-error {{expected string literal as argument of '__arm_inout' attribute}}

clang/test/Sema/aarch64-sme-func-attrs.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -356,16 +356,10 @@ void valid_state_attrs_in_in2(void) __arm_in("za", "za");
356356

357357
// expected-cpp-error@+2 {{missing state for '__arm_in'}}
358358
// expected-error@+1 {{missing state for '__arm_in'}}
359-
void invalid_state_attrs_no_arg1(void) __arm_in;
360-
// expected-cpp-error@+2 {{missing state for '__arm_in'}}
361-
// expected-error@+1 {{missing state for '__arm_in'}}
362-
void invalid_state_attrs_no_arg2(void) __arm_in();
363-
// expected-cpp-error@+2 {{missing state for '__arm_new'}}
364-
// expected-error@+1 {{missing state for '__arm_new'}}
365-
__arm_new void invalid_state_attrs_no_arg2(void);
359+
void invalid_state_attrs_no_arg1(void) __arm_in();
366360
// expected-cpp-error@+2 {{missing state for '__arm_new'}}
367361
// expected-error@+1 {{missing state for '__arm_new'}}
368-
__arm_new() void invalid_state_attrs_no_arg3(void);
362+
__arm_new() void invalid_state_attrs_no_arg2(void);
369363

370364
// expected-cpp-error@+2 {{conflicting attributes for state 'za'}}
371365
// expected-error@+1 {{conflicting attributes for state 'za'}}

clang/utils/TableGen/ClangAttrEmitter.cpp

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3561,27 +3561,12 @@ void EmitClangRegularKeywordAttributeInfo(RecordKeeper &Records,
35613561
if (!isRegularKeywordAttribute(S))
35623562
continue;
35633563
std::vector<Record *> Args = R->getValueAsListOfDefs("Args");
3564-
bool HasArgs = false;
3565-
bool HasOptionalArgs = false;
3566-
for (const auto *Arg : Args) {
3567-
if (Arg->getValueAsBit("Fake"))
3568-
continue;
3569-
HasArgs = true;
3570-
if (Arg->getValueAsBit("Optional"))
3571-
HasOptionalArgs = true;
3572-
else
3573-
break;
3574-
}
3564+
bool HasArgs = llvm::any_of(
3565+
Args, [](const Record *Arg) { return !Arg->getValueAsBit("Fake"); });
35753566

35763567
OS << "KEYWORD_ATTRIBUTE("
3577-
<< S.getSpellingRecord().getValueAsString("Name") << ", ";
3578-
if (HasOptionalArgs)
3579-
OS << "KeywordAttributeParseArgumentsKind::Optional";
3580-
else if (HasArgs)
3581-
OS << "KeywordAttributeParseArgumentsKind::Required";
3582-
else
3583-
OS << "KeywordAttributeParseArgumentsKind::None";
3584-
OS << ")\n";
3568+
<< S.getSpellingRecord().getValueAsString("Name") << ", "
3569+
<< (HasArgs ? "true" : "false") << ")\n";
35853570
}
35863571
OS << "#undef KEYWORD_ATTRIBUTE\n";
35873572
}

0 commit comments

Comments
 (0)