From 842901d0ca0baa25ea510089a21162a6e8ae8f29 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 7 Aug 2019 17:32:12 +0000 Subject: [PATCH] PR c++/81429 - wrong parsing of constructor with C++11 attribute. * parser.c (cp_parser_constructor_declarator_p): Handle the scenario when a parameter declaration begins with [[attribute]]. * g++.dg/cpp0x/gen-attrs-68.C: New test. * g++.dg/cpp0x/gen-attrs-69.C: New test. From-SVN: r274181 --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/parser.c | 4 ++- gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-68.C | 40 +++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-69.C | 40 +++++++++++++++++++++++ 5 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/gen-attrs-68.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/gen-attrs-69.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 64714e0600e..bae5147fca9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-08-07 Marek Polacek + + PR c++/81429 - wrong parsing of constructor with C++11 attribute. + * parser.c (cp_parser_constructor_declarator_p): Handle the scenario + when a parameter declaration begins with [[attribute]]. + 2019-08-07 Marek Polacek PR c++/91346 - Implement P1668R1, allow unevaluated asm in constexpr. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ccf89f0856f..14b724095c4 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -27857,7 +27857,9 @@ 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) + /* A parameter declaration can also begin with [[attribute]]. */ + && !cp_next_tokens_can_be_std_attribute_p (parser)) { tree type; tree pushed_scope = NULL_TREE; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f2e6afc0e8d..e69e59be069 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-08-07 Marek Polacek + + PR c++/81429 - wrong parsing of constructor with C++11 attribute. + * g++.dg/cpp0x/gen-attrs-68.C: New test. + * g++.dg/cpp0x/gen-attrs-69.C: New test. + 2019-08-07 Marek Polacek PR c++/91346 - Implement P1668R1, allow unevaluated asm in constexpr. diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-68.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-68.C new file mode 100644 index 00000000000..6bede0659db --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-68.C @@ -0,0 +1,40 @@ +// PR c++/81429 - wrong parsing of constructor with C++11 attribute. +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wunused-parameter -Wno-pedantic" } + +void fn1([[maybe_unused]] int a) { } +void fn2(int a [[maybe_unused]]) { } +void fn3(__attribute__((unused)) int a) { } +void fn4(int a __attribute__((unused))) { } + +struct S1 { + S1([[maybe_unused]] int a) { } +}; + +struct S2 { + S2([[maybe_unused]] int f, [[maybe_unused]] int a) { } +}; + +struct S3 { + S3(int a [[maybe_unused]]) { } +}; + +struct S4 { + S4(int f [[maybe_unused]], int a [[maybe_unused]]) { } +}; + +struct S5 { + S5(__attribute__((unused)) int a) { } +}; + +struct S6 { + S6(__attribute__((unused)) int f, __attribute__((unused)) int a) { } +}; + +struct S7 { + S7(int a __attribute__((unused))) { } +}; + +struct S8 { + S8(int f __attribute__((unused)), int a __attribute__((unused))) { } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-69.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-69.C new file mode 100644 index 00000000000..43173dbbdf4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-69.C @@ -0,0 +1,40 @@ +// PR c++/81429 - wrong parsing of constructor with C++11 attribute. +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wno-pedantic" } + +void fn1([[maybe_unused]] int); +void fn2(int a [[maybe_unused]]); +void fn3(__attribute__((unused)) int); +void fn4(int __attribute__((unused))); + +struct S1 { + S1([[maybe_unused]] int); +}; + +struct S2 { + S2([[maybe_unused]] int, [[maybe_unused]] int); +}; + +struct S3 { + S3(int a [[maybe_unused]]); +}; + +struct S4 { + S4(int a [[maybe_unused]], int b [[maybe_unused]]); +}; + +struct S5 { + S5(__attribute__((unused)) int); +}; + +struct S6 { + S6(__attribute__((unused)) int, __attribute__((unused)) int); +}; + +struct S7 { + S7(int __attribute__((unused))); +}; + +struct S8 { + S8(int __attribute__((unused)), int __attribute__((unused))); +}; -- 2.30.2