]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/92438 (Function declaration parsed incorrectly with `-std=c++1z`)
authorJakub Jelinek <jakub@redhat.com>
Wed, 22 Jan 2020 16:42:02 +0000 (17:42 +0100)
committerJakub Jelinek <jakub@redhat.com>
Wed, 22 Jan 2020 19:12:54 +0000 (20:12 +0100)
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.

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/attrib61.C [new file with mode: 0644]

index f0e314fd35489b2ed60121ad706db60e0068095f..13601ce975e7f5886d747392652f825ed2440c21 100644 (file)
@@ -1,3 +1,13 @@
+2020-01-22  Jakub Jelinek  <jakub@redhat.com>
+
+       Backported from mainline
+       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.
+
 2020-01-22  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
index 4df5d5797dc27d5b46fb03a8ad006efe684a836a..54b3522dc8ee6a612f444c73649e4c63ad8de146 100644 (file)
@@ -27619,7 +27619,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))
        {
@@ -27627,6 +27635,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)
index 2e507fdfe505bf07e381e2892aeb733b8321cf2e..c306cf6c296ddb6a12400bc165c15d32e51d699f 100644 (file)
@@ -1,3 +1,11 @@
+2020-01-22  Jakub Jelinek  <jakub@redhat.com>
+
+       Backported from mainline
+       2019-12-26  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/92438
+       * g++.dg/ext/attrib61.C: New test.
+
 2020-01-22  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
diff --git a/gcc/testsuite/g++.dg/ext/attrib61.C b/gcc/testsuite/g++.dg/ext/attrib61.C
new file mode 100644 (file)
index 0000000..2318306
--- /dev/null
@@ -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);
+}