diff options
author | Michele Scandale <michele.scandale@gmail.com> | 2020-02-24 07:59:26 -0500 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2020-02-24 08:08:47 -0500 |
commit | bd5b22070b6984d89c13b6cf38c3e54fc98ce291 (patch) | |
tree | c5c1718ce9813ee98a4ac4e772f2358a9bfc2953 /clang/lib/Parse/ParseTentative.cpp | |
parent | 12fed51c0807b0727f9eecdd3dcf774a82fa7ecd (diff) | |
download | llvm-bd5b22070b6984d89c13b6cf38c3e54fc98ce291.zip llvm-bd5b22070b6984d89c13b6cf38c3e54fc98ce291.tar.gz llvm-bd5b22070b6984d89c13b6cf38c3e54fc98ce291.tar.bz2 |
Fix TryParsePtrOperatorSeq.
The syntax rules for ptr-operator allow attributes after *, &,
&&, therefore we should be able to parse the following:
void fn() {
void (*[[attr]] x)() = &fn;
void (&[[attr]] y)() = fn;
void (&&[[attr]] z)() = fn;
}
However the current logic in TryParsePtrOperatorSeq does not consider
the presence of attributes leading to unexpected parsing errors.
Moreover we should also consider _Atomic a possible qualifier that can
appear after the sequence of attribute specifiers.
Diffstat (limited to 'clang/lib/Parse/ParseTentative.cpp')
-rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index ad0a15b..75cc7c2 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -186,21 +186,8 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() { ConsumeToken(); // Skip attributes. - while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec, - tok::kw_alignas)) { - if (Tok.is(tok::l_square)) { - ConsumeBracket(); - if (!SkipUntil(tok::r_square)) - return TPResult::Error; - } else { - ConsumeToken(); - if (Tok.isNot(tok::l_paren)) - return TPResult::Error; - ConsumeParen(); - if (!SkipUntil(tok::r_paren)) - return TPResult::Error; - } - } + if (!TrySkipAttributes()) + return TPResult::Error; if (TryAnnotateOptionalCXXScopeToken()) return TPResult::Error; @@ -781,6 +768,32 @@ Parser::isCXX11AttributeSpecifier(bool Disambiguate, return CAK_NotAttributeSpecifier; } +bool Parser::TrySkipAttributes() { + while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec, + tok::kw_alignas)) { + if (Tok.is(tok::l_square)) { + ConsumeBracket(); + if (Tok.isNot(tok::l_square)) + return false; + ConsumeBracket(); + if (!SkipUntil(tok::r_square) || Tok.isNot(tok::r_square)) + return false; + // Note that explicitly checking for `[[` and `]]` allows to fail as + // expected in the case of the Objective-C message send syntax. + ConsumeBracket(); + } else { + ConsumeToken(); + if (Tok.isNot(tok::l_paren)) + return false; + ConsumeParen(); + if (!SkipUntil(tok::r_paren)) + return false; + } + } + + return true; +} + Parser::TPResult Parser::TryParsePtrOperatorSeq() { while (true) { if (TryAnnotateOptionalCXXScopeToken(true)) @@ -790,9 +803,14 @@ Parser::TPResult Parser::TryParsePtrOperatorSeq() { (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { // ptr-operator ConsumeAnyToken(); + + // Skip attributes. + if (!TrySkipAttributes()) + return TPResult::Error; + while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict, tok::kw__Nonnull, tok::kw__Nullable, - tok::kw__Null_unspecified)) + tok::kw__Null_unspecified, tok::kw__Atomic)) ConsumeToken(); } else { return TPResult::True; |