From patchwork Thu Sep 5 07:15:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1981107 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=f/kUVHUl; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WzrJG5NNZz1yXY for ; Thu, 5 Sep 2024 17:16:30 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 23FE93850200 for ; Thu, 5 Sep 2024 07:16:27 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 0E59A3860C34 for ; Thu, 5 Sep 2024 07:15:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0E59A3860C34 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0E59A3860C34 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1725520557; cv=none; b=sBzEkJKZyuuKQNdQzrX6fkxFbHr9VS18NxWhxvdvZTijEnDgdxjaU/UJGUWLIjvGuA+iu8qErKA8Xt+f9w2az6UK5ZD6idOoPTJ/P421ROb9HiOcW0fUBwkM/2JYFlWwY+pNnszSXVDgrCbtJM6Tt3lN0LelZwJ6PjeG1Te7e6k= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1725520557; c=relaxed/simple; bh=wOHZXpH0cHu3aNiKstPQ4/afYSigJs1WBsbgIT6elMs=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=nCe8lahQ+saGGoY3wrLWjtN3rAiV0obmDQtWRnnMor+EqXLPk6/72a/vBBQia/86TrHEkPuGF3ZahS2nIRiSATe1K84TUjKBhFYZVVyiluL1q9sSWSZOPNBWUovscN6ye2skuIr3o4xvb0IKp1nlcacVGEpWMApL84H8cNJOARM= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1725520540; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=uGdouwx3jVZR/jyg71eJRr/dkcLgsxZaPtSczOCTEC0=; b=f/kUVHUlaKdXR9kyScRcJHf1njvF3EuOJrYw2+IiN0utCw4NaFzLRmBk3Pnn0faUCHoZ5v C4PvUqDujOxeuLEZ7oZcutkjeLGAj1katmhoEWOS9/JyKnE2sg++1lCqOM7rinNnkjZJsK VW4Wj0fuy21cztjo+EmqomFGeeB7y0k= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-451-YGar_H60MQmNcXAd8WsA3Q-1; Thu, 05 Sep 2024 03:15:38 -0400 X-MC-Unique: YGar_H60MQmNcXAd8WsA3Q-1 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A83DB1955D55 for ; Thu, 5 Sep 2024 07:15:37 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.29]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E87401956086; Thu, 5 Sep 2024 07:15:36 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 4857FYk41837150 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 5 Sep 2024 09:15:34 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 4857FX731837149; Thu, 5 Sep 2024 09:15:33 +0200 Date: Thu, 5 Sep 2024 09:15:33 +0200 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: Handle attributes on exception declarations [PR110345] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Hi! This is a continuation of the series for the ignorability of standard attributes, on top of https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661904.html https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661905.html https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661906.html I've added a test for assume attribute diagnostics appertaining to various entities (mostly invalid) and while doing that, I've discovered that attributes on exception declarations were mostly ignored, this patch adds the missing cp_decl_attributes call and also in the cp_parser_type_specifier_seq case differentiates between attributes and std_attributes to be able to differentiate between attributes which apply to the declaration using type-specifier-seq and attributes after the type specifiers. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-09-05 Jakub Jelinek PR c++/110345 * parser.cc (cp_parser_type_specifier_seq): Chain cxx11_attribute_p attributes after any type specifier in the is_declaration case to std_attributes rather than attributes. Set also ds_attribute or ds_std_attribute locations if not yet set. (cp_parser_exception_declaration): Pass &type_specifiers.attributes instead of NULL as last argument, call cp_decl_attributes. * g++.dg/cpp0x/attr-assume1.C: New test. * g++.dg/cpp0x/attr-deprecated1.C: Add tests for attributes after type specifiers before parameter or exception declarations and after parameter or exception declaration declarators. Jakub --- gcc/cp/parser.cc.jj 2024-09-04 12:36:51.903244117 +0200 +++ gcc/cp/parser.cc 2024-09-04 15:13:22.875960509 +0200 @@ -25375,9 +25375,24 @@ cp_parser_type_specifier_seq (cp_parser* || tok->type == CPP_EQ || tok->type == CPP_OPEN_BRACE) break; } - type_specifier_seq->attributes - = attr_chainon (type_specifier_seq->attributes, - cp_parser_attributes_opt (parser)); + location_t attr_loc = cp_lexer_peek_token (parser->lexer)->location; + tree attrs = cp_parser_attributes_opt (parser); + if (seen_type_specifier + && is_declaration + && cxx11_attribute_p (attrs)) + { + type_specifier_seq->std_attributes + = attr_chainon (type_specifier_seq->std_attributes, attrs); + if (type_specifier_seq->locations[ds_std_attribute] == 0) + type_specifier_seq->locations[ds_std_attribute] = attr_loc; + } + else + { + type_specifier_seq->attributes + = attr_chainon (type_specifier_seq->attributes, attrs); + if (type_specifier_seq->locations[ds_attribute] == 0) + type_specifier_seq->locations[ds_attribute] = attr_loc; + } continue; } @@ -29630,7 +29645,12 @@ cp_parser_exception_declaration (cp_pars if (!type_specifiers.any_specifiers_p) return error_mark_node; - return grokdeclarator (declarator, &type_specifiers, CATCHPARM, 1, NULL); + tree decl = grokdeclarator (declarator, &type_specifiers, CATCHPARM, 1, + &type_specifiers.attributes); + if (decl != error_mark_node && type_specifiers.attributes) + cplus_decl_attributes (&decl, type_specifiers.attributes, 0); + + return decl; } /* Parse a throw-expression. --- gcc/testsuite/g++.dg/cpp0x/attr-assume1.C.jj 2024-09-04 12:47:19.356072957 +0200 +++ gcc/testsuite/g++.dg/cpp0x/attr-assume1.C 2024-09-04 15:28:42.486057664 +0200 @@ -0,0 +1,151 @@ +// C++ 26 P2552R3 - On the ignorability of standard attributes +// { dg-do compile { target c++11 } } + +int arr[2]; +struct S { int a, b; }; +S arr2[2]; + +void +foo (int n) +{ + [[assume (n > 0)]]; + [[assume]]; // { dg-error "wrong number of arguments specified for 'assume' attribute" } + [[assume ("abc")]]; + [[assume (1, 2, 3)]]; // { dg-error "wrong number of arguments specified for 'assume' attribute" } + + [[assume (true)]] int x1; // { dg-error "'assume' attribute ignored" } + + auto a = [] [[assume (true)]] () {}; // { dg-error "'assume' attribute ignored" } + auto b = [] constexpr [[assume (true)]] {}; // { dg-error "'assume' attribute ignored" } + // { dg-error "parameter declaration before lambda declaration specifiers only optional with" "" { target c++20_down } .-1 } + // { dg-error "'constexpr' lambda only available with" "" { target c++14_down } .-2 } + auto c = [] noexcept [[assume (true)]] {}; // { dg-error "'assume' attribute ignored" } + // { dg-error "parameter declaration before lambda exception specification only optional with" "" { target c++20_down } .-1 } + auto d = [] () [[assume (true)]] {}; // { dg-error "'assume' attribute ignored" } + auto e = new int [n] [[assume (true)]]; // { dg-warning "attributes ignored on outermost array type in new expression" } + auto e2 = new int [n] [[assume (true)]] [42]; // { dg-warning "attributes ignored on outermost array type in new expression" } + auto f = new int [n][42] [[assume (true)]]; // { dg-error "'assume' attribute ignored" } + [[assume (true)]]; + [[assume (true)]] {} // { dg-warning "attributes at the beginning of statement are ignored" } + [[assume (true)]] if (true) {} // { dg-warning "attributes at the beginning of statement are ignored" } + [[assume (true)]] while (false) {} // { dg-warning "attributes at the beginning of statement are ignored" } + [[assume (true)]] goto lab; // { dg-warning "attributes at the beginning of statement are ignored" } + [[assume (true)]] lab:; // { dg-error "'assume' attribute ignored" } + [[assume (true)]] try {} catch (int) {} // { dg-warning "attributes at the beginning of statement are ignored" } + if ([[assume (true)]] int x = 0) {} // { dg-error "'assume' attribute ignored" } + switch (n) + { + [[assume (true)]] case 1: // { dg-error "'assume' attribute ignored" } + [[assume (true)]] break; // { dg-warning "attributes at the beginning of statement are ignored" } + [[assume (true)]] default: // { dg-error "'assume' attribute ignored" } + break; + } + for ([[assume (true)]] auto a : arr) {} // { dg-error "'assume' attribute ignored" } + for ([[assume (true)]] auto [a, b] : arr2) {} // { dg-error "'assume' attribute ignored" } + // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 } + [[assume (true)]] asm (""); // { dg-warning "attributes ignored on 'asm' declaration" } + try {} catch ([[assume (true)]] int x) {} // { dg-error "'assume' attribute ignored" } + try {} catch ([[assume (true)]] int) {} // { dg-error "'assume' attribute ignored" } + try {} catch (int [[assume (true)]] x) {} // { dg-warning "attribute ignored" } + try {} catch (int [[assume (true)]]) {} // { dg-warning "attribute ignored" } + try {} catch (int x [[assume (true)]]) {} // { dg-error "'assume' attribute ignored" } +} + +[[assume (true)]] int bar (); // { dg-error "'assume' attribute ignored" } +using foobar [[assume (true)]] = int; // { dg-error "'assume' attribute ignored" } +[[assume (true)]] int a; // { dg-error "'assume' attribute ignored" } +[[assume (true)]] auto [b, c] = arr; // { dg-error "'assume' attribute ignored" } + // { dg-error "structured bindings only available with" "" { target c++14_down } .-1 } +[[assume (true)]]; // { dg-warning "attribute ignored" } +inline [[assume (true)]] void baz () {} // { dg-warning "attribute ignored" } + // { dg-error "standard attributes in middle of decl-specifiers" "" { target *-*-* } .-1 } +constexpr [[assume (true)]] int qux () { return 0; } // { dg-warning "attribute ignored" } + // { dg-error "standard attributes in middle of decl-specifiers" "" { target *-*-* } .-1 } +int [[assume (true)]] d; // { dg-warning "attribute ignored" } +int const [[assume (true)]] e = 1; // { dg-warning "attribute ignored" } +struct A {} [[assume (true)]]; // { dg-warning "attribute ignored in declaration of 'struct A'" } +struct A [[assume (true)]]; // { dg-warning "attribute ignored" } +struct A [[assume (true)]] a1; // { dg-warning "attribute ignored" } +A [[assume (true)]] a2; // { dg-warning "attribute ignored" } +enum B { B0 } [[assume (true)]]; // { dg-warning "attribute ignored in declaration of 'enum B'" } +enum B [[assume (true)]]; // { dg-warning "attribute ignored" } +enum B [[assume (true)]] b1; // { dg-warning "attribute ignored" } +B [[assume (true)]] b2; // { dg-warning "attribute ignored" } +struct [[assume (true)]] C {}; // { dg-error "'assume' attribute ignored" } +int f [[assume (true)]]; // { dg-error "'assume' attribute ignored" } +int g[2] [[assume (true)]]; // { dg-error "'assume' attribute ignored" } +int g2 [[assume (true)]] [2]; // { dg-error "'assume' attribute ignored" } +int corge () [[assume (true)]]; // { dg-error "'assume' attribute ignored" } +int *[[assume (true)]] h; // { dg-error "'assume' attribute ignored" } +int & [[assume (true)]] i = f; // { dg-error "'assume' attribute ignored" } +int && [[assume (true)]] j = 0; // { dg-error "'assume' attribute ignored" } +int S::* [[assume (true)]] k; // { dg-error "'assume' attribute ignored" } +auto l = sizeof (int [2] [[assume (true)]]); // { dg-error "'assume' attribute ignored" } +int freddy ([[assume (true)]] int a, // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int, // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int c = 0, // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int = 0); // { dg-error "'assume' attribute ignored" } +void +corge ([[assume (true)]] int a, // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int, // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int c = 0, // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int = 0) // { dg-error "'assume' attribute ignored" } +{ +} +[[assume (true)]] void +garply () // { dg-error "'assume' attribute ignored" } +{ +} +int grault (int [[assume (true)]] a, // { dg-warning "attribute ignored" } + int [[assume (true)]], // { dg-warning "attribute ignored" } + int [[assume (true)]] c = 0, // { dg-warning "attribute ignored" } + int [[assume (true)]] = 0); // { dg-warning "attribute ignored" } +void +waldo (int [[assume (true)]] a, // { dg-warning "attribute ignored" } + int [[assume (true)]], // { dg-warning "attribute ignored" } + int [[assume (true)]] c = 0, // { dg-warning "attribute ignored" } + int [[assume (true)]] = 0) // { dg-warning "attribute ignored" } +{ +} +int plugh (int a [[assume (true)]], // { dg-error "'assume' attribute ignored" } + int b [[assume (true)]] = 0); // { dg-error "'assume' attribute ignored" } +void +thud (int a [[assume (true)]], // { dg-error "'assume' attribute ignored" } + int b [[assume (true)]] = 0) // { dg-error "'assume' attribute ignored" } +{ +} +enum [[assume (true)]] D { D0 }; // { dg-error "'assume' attribute ignored" } +enum class [[assume (true)]] E { E0 }; // { dg-error "'assume' attribute ignored" } +enum F {}; +enum [[assume (true)]] F; // { dg-warning "type attributes ignored after type is already defined" } +enum G { + G0 [[assume (true)]], // { dg-error "'assume' attribute ignored" } + G1 [[assume (true)]] = 2 // { dg-error "'assume' attribute ignored" } +}; +namespace [[assume (true)]] H { using H0 = int; } // { dg-warning "'assume' attribute directive ignored" } */ +namespace [[assume (true)]] {} // { dg-warning "'assume' attribute directive ignored" } +[[assume (true)]] using namespace H; // { dg-warning "'assume' attribute directive ignored" } +struct [[assume (true)]] I // { dg-error "'assume' attribute ignored" } +{ + [[assume (true)]]; // { dg-error "declaration does not declare anything" } + [[assume (true)]] int i; // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int foo (); // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int bar () { return 1; } // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int : 0; // { dg-error "'assume' attribute ignored" } + [[assume (true)]] int i2 : 5; // { dg-error "'assume' attribute ignored" } + [[assume (true)]] static int i3; // { dg-error "'assume' attribute ignored" } + static int i4; +}; +[[assume (true)]] int I::i4 = 0; // { dg-error "'assume' attribute ignored" } +struct J : [[assume (true)]] C {}; // { dg-warning "attributes on base specifiers are ignored" } +#if __cpp_concepts >= 201907L +template +concept K [[assume (true)]] = requires { true; }; // { dg-error "'assume' attribute ignored" "" { target c++20 } } +#endif +typedef int L [[assume (true)]]; // { dg-error "'assume' attribute ignored" } +template +struct M {}; +template <> +struct [[assume (true)]] M { int m; }; // { dg-error "'assume' attribute ignored" } +typedef int N[2] [[assume (true)]]; // { dg-error "'assume' attribute ignored" } +typedef int O [[assume (true)]] [2]; // { dg-error "'assume' attribute ignored" } --- gcc/testsuite/g++.dg/cpp0x/attr-deprecated1.C.jj 2024-09-04 12:36:51.904244104 +0200 +++ gcc/testsuite/g++.dg/cpp0x/attr-deprecated1.C 2024-09-04 15:29:38.233337176 +0200 @@ -46,6 +46,9 @@ foo (int n) [[deprecated]] asm (""); // { dg-warning "attributes ignored on 'asm' declaration" } try {} catch ([[deprecated]] int x) {} try {} catch ([[deprecated]] int) {} + try {} catch (int [[deprecated]] x) {} // { dg-warning "attribute ignored" } + try {} catch (int [[deprecated]]) {} // { dg-warning "attribute ignored" } + try {} catch (int x [[deprecated]]) {} } [[deprecated]] int bar (); @@ -93,6 +96,24 @@ corge ([[deprecated]] int a, garply () { } +int grault (int [[deprecated]] a, // { dg-warning "attribute ignored" } + int [[deprecated]], // { dg-warning "attribute ignored" } + int [[deprecated]] c = 0, // { dg-warning "attribute ignored" } + int [[deprecated]] = 0); // { dg-warning "attribute ignored" } +void +waldo (int [[deprecated]] a, // { dg-warning "attribute ignored" } + int [[deprecated]], // { dg-warning "attribute ignored" } + int [[deprecated]] c = 0, // { dg-warning "attribute ignored" } + int [[deprecated]] = 0) // { dg-warning "attribute ignored" } +{ +} +int plugh (int a [[deprecated]], + int b [[deprecated]] = 0); +void +thud (int a [[deprecated]], + int b [[deprecated]] = 0) +{ +} enum [[deprecated]] D { D0 }; enum class [[deprecated]] E { E0 }; enum F {};