diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-12-26 11:16:01 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-12-26 11:16:01 +0100 |
commit | 7cd268ad6a6f71877744539d17ed53e752774bfa (patch) | |
tree | 3a55ec188547087fe3db9a81420da7db66097d60 | |
parent | ae2bb2a6434d3177b94f78ac707f606ee65f0360 (diff) | |
download | gcc-7cd268ad6a6f71877744539d17ed53e752774bfa.zip gcc-7cd268ad6a6f71877744539d17ed53e752774bfa.tar.gz gcc-7cd268ad6a6f71877744539d17ed53e752774bfa.tar.bz2 |
re PR c++/92438 (Function declaration parsed incorrectly with `-std=c++1z`)
PR c++/92438
* parser.c (cp_parser_constructor_declarator_p): If open paren
is followed by RID_ATTRIBUTE, skip over the attribute tokens and
try to parse type specifier.
* g++.dg/ext/attrib61.C: New test.
From-SVN: r279736
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/attrib61.C | 26 |
4 files changed, 54 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 14c6d32..334438c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-12-26 Jakub Jelinek <jakub@redhat.com> + + PR c++/92438 + * parser.c (cp_parser_constructor_declarator_p): If open paren + is followed by RID_ATTRIBUTE, skip over the attribute tokens and + try to parse type specifier. + 2019-12-23 Richard Sandiford <richard.sandiford@arm.com> PR c++/92789 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c3c968d..c66ef34 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -28493,7 +28493,15 @@ cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags, /* A parameter declaration begins with a decl-specifier, which is either the "attribute" keyword, a storage class specifier, or (usually) a type-specifier. */ - && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer) + && (!cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer) + /* GNU attributes can actually appear both at the start of + a parameter and parenthesized declarator. + S (__attribute__((unused)) int); + is a constructor, but + S (__attribute__((unused)) foo) (int); + is a function declaration. */ + || (cp_parser_allow_gnu_extensions_p (parser) + && cp_next_tokens_can_be_gnu_attribute_p (parser))) /* A parameter declaration can also begin with [[attribute]]. */ && !cp_next_tokens_can_be_std_attribute_p (parser)) { @@ -28501,6 +28509,13 @@ cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags, tree pushed_scope = NULL_TREE; unsigned saved_num_template_parameter_lists; + if (cp_next_tokens_can_be_gnu_attribute_p (parser)) + { + unsigned int n = cp_parser_skip_gnu_attributes_opt (parser, 1); + while (--n) + cp_lexer_consume_token (parser->lexer); + } + /* Names appearing in the type-specifier should be looked up in the scope of the class. */ if (current_class_type) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1a659db..0db2e22 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-12-26 Jakub Jelinek <jakub@redhat.com> + + PR c++/92438 + * g++.dg/ext/attrib61.C: New test. + 2019-12-23 Thomas Schwinge <thomas@codesourcery.com> * c-c++-common/goacc/mdc-1.c: Restrict to LP64, LLP64. diff --git a/gcc/testsuite/g++.dg/ext/attrib61.C b/gcc/testsuite/g++.dg/ext/attrib61.C new file mode 100644 index 0000000..2318306 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib61.C @@ -0,0 +1,26 @@ +// PR c++/92438 +// { dg-do compile } + +typedef struct S { int x; } T; +T (foo) (T x); +T __attribute__((unused)) bar (T x); +struct S (__attribute__((unused)) baz) (T x); +T (__attribute__((unused)) qux) (T x); + +struct U +{ + U (__attribute__((unused)) int); + U (__attribute__((unused)) corge) (int); +}; + +void +test () +{ + T a, b; + a = foo (b); + b = bar (a); + a = baz (b); + b = qux (a); + U u (5); + U v = u.corge (3); +} |