From patchwork Fri Sep 1 13:34:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 137397 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c792:0:b0:3f2:4152:657d with SMTP id b18csp890044vqu; Fri, 1 Sep 2023 06:35:09 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGFe+wsvWoJjyghYsRMVK+iPeHZwsszOqkKEy7QADaVn0+IfAW/CtTtqlJUjPW3O/7LQ/HL X-Received: by 2002:a17:906:224a:b0:9a1:b85d:c95d with SMTP id 10-20020a170906224a00b009a1b85dc95dmr2093735ejr.50.1693575309409; Fri, 01 Sep 2023 06:35:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1693575309; cv=none; d=google.com; s=arc-20160816; b=kQ2zRNJvgKG14Vb+obVHgUWc3BgtsKvw5RHdAzNu+UxUIJ+zcR5nPr8xMsxXnJwLKt fbUHWkRtZMvnSW3F6uOmPh0de5300EF8CJqRpr1nmjFNI7ijvO7+UUykTGC7Qr4Ictx/ nd6T402/mloGaqxNOk00Bm7e1sguDyw9JTf0tKw1uRbbmlXXI+3Fe2FkVDcF00RUbDzm jIt61XgvFxvDFposZ9FUdOIcEh3VA/QDJHHKb/DoCwuJTrSQ3XTGDF7aAwzr/ur5NYLG +KOh5zFmQUChjKVPYfEvy+TjBCwh0SubsTF9BuHa9xJ2DnULkCDd/7VyGmO/roJLPNp+ BreQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:in-reply-to:mime-version:references:message-id :subject:cc:to:date:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=EIbgcqM0mUQ5qWORMzygMtCnHZiopMASu41oZ8QR65w=; fh=0xZT+NBKSeH8qOu04/61f1ZGePpF4jF/gxp331YE14k=; b=vm5hqlRw2VCu51KBsrgkGqdgMMJE+mDQRkktGCxUC4ElAMTSychMyUMkyCF9Z2ZnaB OQZqr3a2bWpIOhbB+4hb+fB43YLhPq6DSrdY07P9TNiqOKnVuTItR3SwyFokk3inxOVm 9yLlwwbd6aIJv3qMt5cE40efI2mnh/vBSLfXxGaUp8W5A4c34YDuik/D2BkuuO8abRTX qLwH/6Ekvrpb+35mT/t0hlkc1AXfWF6OYfYNEhcVW0/z4NpdXHlNyI+IAuAyyoqa6xxH ycHrj0VTjB8RW16F3ElPVRlsHyr9QH6nLKbABU1IyzpfBxEhTlAZXERvI58CHMIRHuCY ByAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kr4ztn03; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id si28-20020a170906cedc00b00992f8116abdsi2514971ejb.480.2023.09.01.06.35.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Sep 2023 06:35:09 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kr4ztn03; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 38BE73856DF8 for ; Fri, 1 Sep 2023 13:35:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 38BE73856DF8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1693575308; bh=EIbgcqM0mUQ5qWORMzygMtCnHZiopMASu41oZ8QR65w=; h=Date:To:Cc:Subject:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=kr4ztn036TNQgtN817qc+gEMNQ9a9FIcpa2KW3We4tU5LqaQmSzfmqff7/EteliT8 zNDUr6FiDwHrwMIpEBqWyXXKzLboemcxCRVEy88olOiwm/FWDodkwjGFE+ZoR2uJI2 m7WA9qtNOoprLpyQO1Ofjo/WQARyGsRFTT/WHv+c= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id 5883D38582B0 for ; Fri, 1 Sep 2023 13:34:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5883D38582B0 Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-34-MkBMeh9dOM6Sj1ulVTpdFQ-1; Fri, 01 Sep 2023 09:34:20 -0400 X-MC-Unique: MkBMeh9dOM6Sj1ulVTpdFQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7270A29DD998 for ; Fri, 1 Sep 2023 13:34:20 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.16]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 196CF40C84A5; Fri, 1 Sep 2023 13:34:19 +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 381DYIWv2768479 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 1 Sep 2023 15:34:18 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 381DYI1G2768478; Fri, 1 Sep 2023 15:34:18 +0200 Date: Fri, 1 Sep 2023 15:34:18 +0200 To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] c++, v2: Diagnose [basic.scope.block]/2 violations even for block externs [PR52953] Message-ID: References: <495f5797-fbb9-e9f6-faa4-af994782edd5@redhat.com> MIME-Version: 1.0 In-Reply-To: <495f5797-fbb9-e9f6-faa4-af994782edd5@redhat.com> X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham 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: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1775842423938185523 X-GMAIL-MSGID: 1775842423938185523 On Thu, Aug 31, 2023 at 05:46:28PM -0400, Jason Merrill wrote: > I've suggested this to Core. Thanks. > > So, I'm not really sure what to do. Intuitively the patch seems right > > because even block externs redeclare stuff and change meaning of the > > identifiers and void foo () { int i; extern int i (int); } is rejected > > by all compilers. > > I think this direction makes sense, though we might pedwarn on these rather > than error to reduce possible breakage. It wasn't clear to me whether you want to make those pedwarns just for the DECL_EXTERNAL cases, ones that actually changed, or all others as well (which were errors or permerrors depending on the case). I've implemented the former, kept existing behavior of !DECL_EXTERNAL. > > 2023-08-31 Jakub Jelinek > > > > PR c++/52953 > > * name-lookup.cc (check_local_shadow): Defer punting on > > DECL_EXTERNAL (decl) from the start of function to right before > > the -Wshadow* checks. > > Don't we want to consider externs for the -Wshadow* checks as well? I think that is a good idea (though dunno how much it will trigger in real-world), but there is one case I've excluded, the global variable shadowing case, because warning that int z; void foo () { extern int z; z = 1; } shadows the global var would be incorrect, it is the same var. It is true that int y; namespace N { void bar () { extern int y; y = 1; } } shadows ::y but it is unclear how to differentiate those two cases with the information we have at check_local_shadow time. I've also found one spot which wasn't using auto_diagnostic_group d; on a pair of error_at/inform. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2023-09-01 Jakub Jelinek PR c++/52953 * name-lookup.cc (check_local_shadow): Don't punt early for DECL_EXTERNAL decls, instead just disable the shadowing of namespace decls check for those and emit a pedwarn rather than error_at for those. Add missing auto_diagnostic_group. Formatting fix. * g++.dg/diagnostic/redeclaration-4.C: New test. * g++.dg/diagnostic/redeclaration-5.C: New test. * g++.dg/warn/Wshadow-19.C: New test. Jakub --- gcc/cp/name-lookup.cc.jj 2023-09-01 10:21:03.658118594 +0200 +++ gcc/cp/name-lookup.cc 2023-09-01 11:30:10.868516494 +0200 @@ -3096,10 +3096,6 @@ check_local_shadow (tree decl) if (TREE_CODE (decl) == PARM_DECL && !DECL_CONTEXT (decl)) return; - /* External decls are something else. */ - if (DECL_EXTERNAL (decl)) - return; - tree old = NULL_TREE; cp_binding_level *old_scope = NULL; if (cxx_binding *binding = outer_binding (DECL_NAME (decl), NULL, true)) @@ -3130,11 +3126,9 @@ check_local_shadow (tree decl) && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ()) && TREE_CODE (old) == PARM_DECL && DECL_NAME (decl) != this_identifier) - { - error_at (DECL_SOURCE_LOCATION (old), - "lambda parameter %qD " - "previously declared as a capture", old); - } + error_at (DECL_SOURCE_LOCATION (old), + "lambda parameter %qD " + "previously declared as a capture", old); return; } /* Don't complain if it's from an enclosing function. */ @@ -3156,10 +3150,18 @@ check_local_shadow (tree decl) in the outermost block of the function definition. */ if (b->kind == sk_function_parms) { - error_at (DECL_SOURCE_LOCATION (decl), - "declaration of %q#D shadows a parameter", decl); - inform (DECL_SOURCE_LOCATION (old), - "%q#D previously declared here", old); + auto_diagnostic_group d; + bool emit = true; + if (DECL_EXTERNAL (decl)) + emit = pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic, + "declaration of %q#D shadows a parameter", + decl); + else + error_at (DECL_SOURCE_LOCATION (decl), + "declaration of %q#D shadows a parameter", decl); + if (emit) + inform (DECL_SOURCE_LOCATION (old), + "%q#D previously declared here", old); return; } } @@ -3185,10 +3187,16 @@ check_local_shadow (tree decl) && (old_scope->kind == sk_cond || old_scope->kind == sk_for)) { auto_diagnostic_group d; - error_at (DECL_SOURCE_LOCATION (decl), - "redeclaration of %q#D", decl); - inform (DECL_SOURCE_LOCATION (old), - "%q#D previously declared here", old); + bool emit = true; + if (DECL_EXTERNAL (decl)) + emit = pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic, + "redeclaration of %q#D", decl); + else + error_at (DECL_SOURCE_LOCATION (decl), + "redeclaration of %q#D", decl); + if (emit) + inform (DECL_SOURCE_LOCATION (old), + "%q#D previously declared here", old); return; } /* C++11: @@ -3314,6 +3322,7 @@ check_local_shadow (tree decl) || (TREE_CODE (old) == TYPE_DECL && (!DECL_ARTIFICIAL (old) || TREE_CODE (decl) == TYPE_DECL))) + && !DECL_EXTERNAL (decl) && !instantiating_current_function_p () && !warning_suppressed_p (decl, OPT_Wshadow)) /* XXX shadow warnings in outer-more namespaces */ --- gcc/testsuite/g++.dg/diagnostic/redeclaration-4.C.jj 2023-09-01 10:46:15.646025458 +0200 +++ gcc/testsuite/g++.dg/diagnostic/redeclaration-4.C 2023-09-01 10:46:15.646025458 +0200 @@ -0,0 +1,167 @@ +// PR c++/52953 +// { dg-do compile } +// { dg-options "-pedantic-errors -Wno-switch-unreachable" } + +void +foo (int x) // { dg-message "'int x' previously declared here" } +{ + extern int x; // { dg-error "declaration of 'int x' shadows a parameter" } +} + +void +bar (int x) // { dg-message "'int x' previously declared here" } +try +{ + extern int x; // { dg-error "declaration of 'int x' shadows a parameter" } +} +catch (...) +{ +} + +volatile int v; + +void +baz () +{ +#if __cplusplus >= 201103L + auto f = [] (int x) { extern int x; };// { dg-error "declaration of 'int x' shadows a parameter" "" { target c++11 } } + // { dg-message "'int x' previously declared here" "" { target c++11 } .-1 } +#endif + if (int x = 1) // { dg-message "'int x' previously declared here" } + { + extern int x; // { dg-error "redeclaration of 'int x'" } + } + if (int x = 0) // { dg-message "'int x' previously declared here" } + ; + else + { + extern int x; // { dg-error "redeclaration of 'int x'" } + } + if (int x = 1) // { dg-message "'int x' previously declared here" } + extern int x; // { dg-error "redeclaration of 'int x'" } + if (int x = 0) // { dg-message "'int x' previously declared here" } + ; + else + extern int x; // { dg-error "redeclaration of 'int x'" } + switch (int x = 1) // { dg-message "'int x' previously declared here" } + { + extern int x; // { dg-error "redeclaration of 'int x'" } + default:; + } + switch (int x = 1) // { dg-message "'int x' previously declared here" } + extern int x; // { dg-error "redeclaration of 'int x'" } + while (int x = v) + { + extern int x; // { dg-error "'int x' conflicts with a previous declaration" } + } + while (int x = v) + extern int x; // { dg-error "'int x' conflicts with a previous declaration" } + for (int x = v; x; ++x) // { dg-message "'int x' previously declared here" } + { + extern int x; // { dg-error "redeclaration of 'int x'" } + } + for (int x = v; x; ++x) // { dg-message "'int x' previously declared here" } + extern int x; // { dg-error "redeclaration of 'int x'" } + for (; int x = v; ) + { + extern int x; // { dg-error "'int x' conflicts with a previous declaration" } + } + for (; int x = v; ) + extern int x; // { dg-error "'int x' conflicts with a previous declaration" } + try + { + } + catch (int x) // { dg-message "'int x' previously declared here" } + { + extern int x; // { dg-error "redeclaration of 'int x'" } + } +} + +void +corge (int x) // { dg-message "'int x' previously declared here" } +try +{ +} +catch (...) +{ + extern int x; // { dg-error "redeclaration of 'int x'" } +} + +void +fred (int x) // { dg-message "'int x' previously declared here" } +try +{ +} +catch (int) +{ +} +catch (long) +{ + extern int x; // { dg-error "redeclaration of 'int x'" } +} + +void +garply (int x) +{ + try + { + extern int x; + } + catch (...) + { + extern int x; + } +} + +struct S +{ + S (int x) // { dg-message "'int x' previously declared here" } + try : s (x) + { + extern int x; // { dg-error "declaration of 'int x' shadows a parameter" } + } + catch (...) + { + } + int s; +}; + +struct T +{ + T (int x) // { dg-message "'int x' previously declared here" } + try : t (x) + { + } + catch (...) + { + extern int x; // { dg-error "redeclaration of 'int x'" } + } + int t; +}; + +struct U +{ + U (int x) : u (x) + { + try + { + extern int x; + } + catch (...) + { + extern int x; + } + } + int u; +}; + +struct V +{ + V (int x) : v (x) + { + { + extern int x; + } + } + int v; +}; --- gcc/testsuite/g++.dg/diagnostic/redeclaration-5.C.jj 2023-09-01 10:46:15.646025458 +0200 +++ gcc/testsuite/g++.dg/diagnostic/redeclaration-5.C 2023-09-01 10:46:15.646025458 +0200 @@ -0,0 +1,167 @@ +// PR c++/52953 +// { dg-do compile } +// { dg-options "-pedantic-errors -Wno-switch-unreachable" } + +void +foo (int x) // { dg-message "'int x' previously declared here" } +{ + extern int x (int); // { dg-error "declaration of 'int x\\\(int\\\)' shadows a parameter" } +} + +void +bar (int x) // { dg-message "'int x' previously declared here" } +try +{ + extern int x (int); // { dg-error "declaration of 'int x\\\(int\\\)' shadows a parameter" } +} +catch (...) +{ +} + +volatile int v; + +void +baz () +{ +#if __cplusplus >= 201103L + auto f = [] (int x) { extern int x (int); };// { dg-error "declaration of 'int x\\\(int\\\)' shadows a parameter" "" { target c++11 } } + // { dg-message "'int x' previously declared here" "" { target c++11 } .-1 } +#endif + if (int x = 1) // { dg-message "'int x' previously declared here" } + { + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + } + if (int x = 0) // { dg-message "'int x' previously declared here" } + ; + else + { + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + } + if (int x = 1) // { dg-message "'int x' previously declared here" } + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + if (int x = 0) // { dg-message "'int x' previously declared here" } + ; + else + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + switch (int x = 1) // { dg-message "'int x' previously declared here" } + { + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + default:; + } + switch (int x = 1) // { dg-message "'int x' previously declared here" } + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + while (int x = v) + { + extern int x (int); // { dg-error "'int x\\\(int\\\)' redeclared as different kind of entity" } + } + while (int x = v) + extern int x (int); // { dg-error "'int x\\\(int\\\)' redeclared as different kind of entity" } + for (int x = v; x; ++x) // { dg-message "'int x' previously declared here" } + { + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + } + for (int x = v; x; ++x) // { dg-message "'int x' previously declared here" } + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + for (; int x = v; ) + { + extern int x (int); // { dg-error "'int x\\\(int\\\)' redeclared as different kind of entity" } + } + for (; int x = v; ) + extern int x (int); // { dg-error "'int x\\\(int\\\)' redeclared as different kind of entity" } + try + { + } + catch (int x) // { dg-message "'int x' previously declared here" } + { + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + } +} + +void +corge (int x) // { dg-message "'int x' previously declared here" } +try +{ +} +catch (...) +{ + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } +} + +void +fred (int x) // { dg-message "'int x' previously declared here" } +try +{ +} +catch (int) +{ +} +catch (long) +{ + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } +} + +void +garply (int x) +{ + try + { + extern int x (int); + } + catch (...) + { + extern int x (int); + } +} + +struct S +{ + S (int x) // { dg-message "'int x' previously declared here" } + try : s (x) + { + extern int x (int); // { dg-error "declaration of 'int x\\\(int\\\)' shadows a parameter" } + } + catch (...) + { + } + int s; +}; + +struct T +{ + T (int x) // { dg-message "'int x' previously declared here" } + try : t (x) + { + } + catch (...) + { + extern int x (int); // { dg-error "redeclaration of 'int x\\\(int\\\)'" } + } + int t; +}; + +struct U +{ + U (int x) : u (x) + { + try + { + extern int x (int); + } + catch (...) + { + extern int x (int); + } + } + int u; +}; + +struct V +{ + V (int x) : v (x) + { + { + extern int x (int); + } + } + int v; +}; --- gcc/testsuite/g++.dg/warn/Wshadow-19.C.jj 2023-09-01 11:35:21.092200057 +0200 +++ gcc/testsuite/g++.dg/warn/Wshadow-19.C 2023-09-01 11:37:15.997598483 +0200 @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options "-Wshadow" } + +void +foo (int x) +{ + int y = 1; + { + extern int x; // { dg-warning "declaration of 'int x' shadows a parameter" } + extern int y; // { dg-warning "declaration of 'y' shadows a previous local" } + } +#if __cplusplus >= 201102L + auto fn = [x] () { extern int x; return 0; }; // { dg-warning "declaration of 'x' shadows a lambda capture" "" { target c++11 } } +#endif +} + +int z; + +struct S +{ + int x; + void foo () + { + extern int x; // { dg-warning "declaration of 'x' shadows a member of 'S'" } + extern int z; + } +};