On 5/9/23 15:23, Jakub Jelinek wrote:
On Tue, May 09, 2023 at 01:17:09PM -0400, Jason Merrill wrote:
How about changing cp_parser_std_attribute to set TREE_VALUE to
error_mark_node if it skips arguments?
In limited testing that seems to work (tried
GXX_TESTSUITE_STDS=98,11,14,17,20,2b make -j32 -k check-g++
RUNTESTFLAGS='dg.exp=*attr*'
so far with it).
Will bootstrap/regtest it tonight.
Ok if it passes?
OK.
2023-05-09 Jakub Jelinek <ja...@redhat.com>
PR c++/109756
* parser.cc (cp_parser_std_attribute): For unknown attributes with
arguments set TREE_VALUE (attribute) to error_mark_node after skipping
the balanced tokens.
(cp_parser_std_attribute_list): If ... is used after attribute without
arguments, diagnose it and return error_mark_node. If
TREE_VALUE (attribute) is error_mark_node, don't call
make_pack_expansion nor return early error_mark_node.
* g++.dg/cpp0x/gen-attrs-78.C: New test.
--- gcc/cp/parser.cc.jj 2023-04-25 16:40:42.010723809 +0200
+++ gcc/cp/parser.cc 2023-05-09 20:22:42.025601924 +0200
@@ -29468,9 +29468,12 @@ cp_parser_std_attribute (cp_parser *pars
}
/* For unknown attributes, just skip balanced tokens instead of
- trying to parse the arguments. */
+ trying to parse the arguments. Set TREE_VALUE (attribute) to
+ error_mark_node to distinguish skipped arguments from attributes
+ with no arguments. */
for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1; n; --n)
cp_lexer_consume_token (parser->lexer);
+ TREE_VALUE (attribute) = error_mark_node;
return attribute;
}
@@ -29562,7 +29565,13 @@ cp_parser_std_attribute_list (cp_parser
if (attribute == NULL_TREE)
error_at (token->location,
"expected attribute before %<...%>");
- else
+ else if (TREE_VALUE (attribute) == NULL_TREE)
+ {
+ error_at (token->location, "attribute with no arguments "
+ "contains no parameter packs");
+ return error_mark_node;
+ }
+ else if (TREE_VALUE (attribute) != error_mark_node)
{
tree pack = make_pack_expansion (TREE_VALUE (attribute));
if (pack == error_mark_node)
--- gcc/testsuite/g++.dg/cpp0x/gen-attrs-78.C.jj 2023-05-08
12:33:13.387581760 +0200
+++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-78.C 2023-05-08 12:32:23.146301128
+0200
@@ -0,0 +1,29 @@
+// PR c++/109756
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-attributes" }
+
+template <int ...args>
+[[noreturn...]] // { dg-error "attribute
with no arguments contains no parameter packs" }
+[[deprecated...]] // { dg-error "attribute with no
arguments contains no parameter packs" }
+[[nodiscard...]] // { dg-error "attribute with no
arguments contains no parameter packs" }
+int foo (int x)
+{
+ switch (x)
+ {
+ case 1:
+ [[likely...]]; // { dg-error "attribute with no
arguments contains no parameter packs" }
+ [[fallthrough...]]; // { dg-error "attribute with no
arguments contains no parameter packs" }
+ case 2:
+ [[unlikely...]]; // { dg-error "attribute with no
arguments contains no parameter packs" }
+
+ break;
+ default:
+ break;
+ }
+ struct T {};
+ struct S { [[no_unique_address...]] T t; }; // { dg-error "attribute with no
arguments contains no parameter packs" }
+ for (;;)
+ ;
+}
+
+int a = foo <1, 2, 3> (4);
Jakub