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? 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