c++, v2: Reject attributes without arguments used as pack expansion [PR109756]
Checks
Commit Message
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 <jakub@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.
Jakub
Comments
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 <jakub@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
>
@@ -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)
@@ -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);