From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 84ED9385737B for ; Mon, 29 Aug 2022 20:01:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 84ED9385737B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1661803267; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=tEUUE2WH5MhOV0pLWFCVHPx4U3QSe8I7A6ZTszzjWZA=; b=OFV/2WLrJRBINLJum8RGTlt8ZuTHQkSq4g/PzXLt3qrCuohgAoTYJrVqhY2lGVCAFXgCCW gsYyfneBKkcVFR8I7CwDy1xGVFfcMTSmXh6JLjPI/xkVyXcCD8FtqJCHNR+HPKJMgTv7oT opte++eeIYvTg1iU5Hgnb7ZRlm92QnU= Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-631-uwk1J132NmKD57PR8QX9uA-1; Mon, 29 Aug 2022 16:01:04 -0400 X-MC-Unique: uwk1J132NmKD57PR8QX9uA-1 Received: by mail-qk1-f200.google.com with SMTP id ay10-20020a05620a178a00b006bbcab9d554so7456955qkb.13 for ; Mon, 29 Aug 2022 13:01:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date:x-gm-message-state:from:to:cc; bh=tEUUE2WH5MhOV0pLWFCVHPx4U3QSe8I7A6ZTszzjWZA=; b=yfiUNsKWDy71YJlzZmoU/ECyU4wqM0ciDthK7BhSXlj+f3GNaVJFNdJsNgaNIbyZwF PFruSXJ6hpUGU1ey4MZsmZyXTBWSL1CZffo567j1qm3PyNGyIp2PumpPVYjTWF4RG8xs tyDpbkA4hPjx8zBi1DvrieKR/lgtY7OnwWv/X6tDA3JsQDLw+2wBOB7LUv9GFmoWe6uW 7HUvM5HqAXnmZ4LnXhdzelFabD7IZ7715dQaiwfeQJyrGdlEYZdOTTcvtA4VXio10zBU 0IVB4vykoAvuXjtOplIiecOoO+h8bF1Ngq3MPEZ1HERRmyKZ9aq/MwKVtMVZSKyU8Cf6 oz/g== X-Gm-Message-State: ACgBeo0fKC9ibBKI9Srs5cIhN6Byeqo4S8adzR68V3v8irkDkR7XABPq f8Gk5rNxINZTWI4YCpGWVUHVekLuCva15DtMFD5AJUqjLbhDi7DHZzHA8v/OZkCSSdXNSRJWRU2 VcXysfD0WaqB32pqHDQ== X-Received: by 2002:a05:620a:488e:b0:6bb:3f84:d175 with SMTP id ea14-20020a05620a488e00b006bb3f84d175mr9440931qkb.587.1661803263458; Mon, 29 Aug 2022 13:01:03 -0700 (PDT) X-Google-Smtp-Source: AA6agR4zfPSU9F0UUy3zEOCnUOprBYUM4bAOo08n4pFmIHcmF+cZZP6YuVSUQl9WykKZ3qnapQ3MfQ== X-Received: by 2002:a05:620a:488e:b0:6bb:3f84:d175 with SMTP id ea14-20020a05620a488e00b006bb3f84d175mr9440899qkb.587.1661803263074; Mon, 29 Aug 2022 13:01:03 -0700 (PDT) Received: from redhat.com ([2601:184:4780:4310::e531]) by smtp.gmail.com with ESMTPSA id 17-20020a05620a06d100b006b9815a05easm6261346qky.26.2022.08.29.13.01.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Aug 2022 13:01:02 -0700 (PDT) Date: Mon, 29 Aug 2022 16:01:00 -0400 From: Marek Polacek To: Jason Merrill Cc: GCC Patches Subject: [PATCH v2] c++: Fix C++11 attribute propagation [PR106712] Message-ID: References: <20220826230150.328756-1-polacek@redhat.com> <95c29538-938d-1e24-95ed-3b2a402980d4@redhat.com> MIME-Version: 1.0 In-Reply-To: <95c29538-938d-1e24-95ed-3b2a402980d4@redhat.com> User-Agent: Mutt/2.2.6 (2022-06-05) X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-12.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Mon, Aug 29, 2022 at 01:32:29PM -0400, Jason Merrill wrote: > On 8/26/22 19:01, Marek Polacek wrote: > > When we have > > > > [[noreturn]] int fn1 [[nodiscard]](), fn2(); > > > > "noreturn" should apply to both fn1 and fn2 but "nodiscard" only to fn1: > > [dcl.pre]/3: "The attribute-specifier-seq appertains to each of > > the entities declared by the declarators of the init-declarator-list." > > [dcl.spec.general]: "The attribute-specifier-seq affects the type > > only for the declaration it appears in, not other declarations involving > > the same type." > > > > As Ed Catmur correctly analyzed, this is because, for the test above, > > we call start_decl with prefix_attributes=noreturn, but this line: > > > > attributes = attr_chainon (attributes, prefix_attributes); > > > > results in attributes == prefix_attributes, because chainon sees > > that attributes is null so it just returns prefix_attributes. Then > > in grokdeclarator we reach > > > > *attrlist = attr_chainon (*attrlist, declarator->std_attributes); > > > > which modifies prefix_attributes so now it's "noreturn, nodiscard" > > and so fn2 is wrongly marked nodiscard as well. Fixed by copying > > prefix_attributes. > > How about reversing the order of arguments to the call in grokdeclarator, so > that the prefix attributes can remain shared at the end of the list? Thanks, that seems like a cheaper solution. It works because this way we tack the prefix attributes onto ->std_attributes, avoiding modifying prefix_attributes. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? -- >8 -- When we have [[noreturn]] int fn1 [[nodiscard]](), fn2(); "noreturn" should apply to both fn1 and fn2 but "nodiscard" only to fn1: [dcl.pre]/3: "The attribute-specifier-seq appertains to each of the entities declared by the declarators of the init-declarator-list." [dcl.spec.general]: "The attribute-specifier-seq affects the type only for the declaration it appears in, not other declarations involving the same type." As Ed Catmur correctly analyzed, this is because, for the test above, we call start_decl with prefix_attributes=noreturn, but this line: attributes = attr_chainon (attributes, prefix_attributes); results in attributes == prefix_attributes, because chainon sees that attributes is null so it just returns prefix_attributes. Then in grokdeclarator we reach *attrlist = attr_chainon (*attrlist, declarator->std_attributes); which modifies prefix_attributes so now it's "noreturn, nodiscard" and so fn2 is wrongly marked nodiscard as well. Fixed by reversing the order of arguments to attr_chainon. That way, we tack the prefix attributes onto ->std_attributes, avoiding modifying prefix_attributes. PR c++/106712 gcc/cp/ChangeLog: * decl.cc (grokdeclarator): Reverse the order of arguments to attr_chainon. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/gen-attrs-77.C: New test. --- gcc/cp/decl.cc | 2 +- gcc/testsuite/g++.dg/cpp0x/gen-attrs-77.C | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/gen-attrs-77.C diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index d46a347a6c7..b72b2a8456b 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -13474,7 +13474,7 @@ grokdeclarator (const cp_declarator *declarator, /* [dcl.meaning]/1: The optional attribute-specifier-seq following a declarator-id appertains to the entity that is declared. */ if (declarator->std_attributes != error_mark_node) - *attrlist = attr_chainon (*attrlist, declarator->std_attributes); + *attrlist = attr_chainon (declarator->std_attributes, *attrlist); else /* We should have already diagnosed the issue (c++/78344). */ gcc_assert (seen_error ()); diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-77.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-77.C new file mode 100644 index 00000000000..2c41c62f33b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-77.C @@ -0,0 +1,17 @@ +// PR c++/106712 +// { dg-do compile { target c++11 } } + +[[noreturn]] int f1 [[nodiscard]](), f2 (); +[[nodiscard]] int f3 (), f4 (); +int f5 [[nodiscard]](), f6 (); + +int +main () +{ + f1 (); // { dg-warning "ignoring" } + f2 (); + f3 (); // { dg-warning "ignoring" } + f4 (); // { dg-warning "ignoring" } + f5 (); // { dg-warning "ignoring" } + f6 (); +} base-commit: 60d1d296b42b22b08d4eaa38bea02100c07261ac -- 2.37.2