michele.scandale created this revision. michele.scandale added reviewers: rjmccall, rsmith. Herald added a project: clang. Herald added a subscriber: cfe-commits. michele.scandale updated this revision to Diff 244756. michele.scandale added a comment.
Missed GNU style attributes 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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D74643 Files: clang/lib/Parse/ParseTentative.cpp clang/test/CXX/dcl.decl/p4-0x.cpp Index: clang/test/CXX/dcl.decl/p4-0x.cpp =================================================================== --- clang/test/CXX/dcl.decl/p4-0x.cpp +++ clang/test/CXX/dcl.decl/p4-0x.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// expected-no-diagnostics struct X { void f() &; @@ -7,3 +6,11 @@ }; void (X::*pmf)() & = &X::f; + +void fn() { + void (*[[attr]] fn_ptr)() = &fn; // expected-warning{{unknown attribute 'attr' ignored}} + void (*[[attrA]] *[[attrB]] fn_ptr_ptr)() = &fn_ptr; // expected-warning{{unknown attribute 'attrA' ignored}} expected-warning{{unknown attribute 'attrB' ignored}} + + void (&[[attr]] fn_lref)() = fn; // expected-warning{{unknown attribute 'attr' ignored}} + void (&&[[attr]] fn_rref)() = fn; // expected-warning{{unknown attribute 'attr' ignored}} +} Index: clang/lib/Parse/ParseTentative.cpp =================================================================== --- clang/lib/Parse/ParseTentative.cpp +++ clang/lib/Parse/ParseTentative.cpp @@ -790,6 +790,24 @@ (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { // ptr-operator ConsumeAnyToken(); + + // 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; + } + } + while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict, tok::kw__Nonnull, tok::kw__Nullable, tok::kw__Null_unspecified))
Index: clang/test/CXX/dcl.decl/p4-0x.cpp =================================================================== --- clang/test/CXX/dcl.decl/p4-0x.cpp +++ clang/test/CXX/dcl.decl/p4-0x.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// expected-no-diagnostics struct X { void f() &; @@ -7,3 +6,11 @@ }; void (X::*pmf)() & = &X::f; + +void fn() { + void (*[[attr]] fn_ptr)() = &fn; // expected-warning{{unknown attribute 'attr' ignored}} + void (*[[attrA]] *[[attrB]] fn_ptr_ptr)() = &fn_ptr; // expected-warning{{unknown attribute 'attrA' ignored}} expected-warning{{unknown attribute 'attrB' ignored}} + + void (&[[attr]] fn_lref)() = fn; // expected-warning{{unknown attribute 'attr' ignored}} + void (&&[[attr]] fn_rref)() = fn; // expected-warning{{unknown attribute 'attr' ignored}} +} Index: clang/lib/Parse/ParseTentative.cpp =================================================================== --- clang/lib/Parse/ParseTentative.cpp +++ clang/lib/Parse/ParseTentative.cpp @@ -790,6 +790,24 @@ (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { // ptr-operator ConsumeAnyToken(); + + // 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; + } + } + while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict, tok::kw__Nonnull, tok::kw__Nullable, tok::kw__Null_unspecified))
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits