From patchwork Sun Oct 30 19:53:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 689036 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3t6SqG0jLBz9sD6 for ; Mon, 31 Oct 2016 06:53:44 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=GxVocdg0; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=G2tVAtf7dEJAS4R3q BPws+P7ltQcf2Ckx2gQ8P51tOvGbAszsjk5EQREP0qpieGqnX272SMMz78yuZ+YS 5wk3iUrtMVgVZYVS82uAmBafX5CGQ2CrnUcrfYQq4afYDbWRtKFmP+jOyg83XuNp 4oOkiolqJkpn8GqS2DBzNmxhSY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=fCqHuj21k12BFl04GjHJqEv CyVM=; b=GxVocdg0aUYp/8W+e4kpZ8/Mw2Lkx4c+K3csZrFlj1wYuZ3SPFZHf+W 55JeBME3Vdknk8T7hQkqeVEuQ6Xs8a1UpT3gQXvXKCI199j9n188hOIrFoxAlXX5 Tde20gwwzjCy6bKtfBsaYcENvxr6oBDejJI0uX71sne852ONZ1UI= Received: (qmail 93918 invoked by alias); 30 Oct 2016 19:53:34 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 93391 invoked by uid 89); 30 Oct 2016 19:53:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.4 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=0.3, 1, 22, H*Ad:U*bonzini, HTo:U*jim X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 30 Oct 2016 19:53:23 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9432631B301; Sun, 30 Oct 2016 19:53:21 +0000 (UTC) Received: from stream.wildebeest.org (ovpn-116-32.ams2.redhat.com [10.36.116.32]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u9UJrJWF008019 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sun, 30 Oct 2016 15:53:20 -0400 Received: by stream.wildebeest.org (Postfix, from userid 1000) id EE0A810158E; Sun, 30 Oct 2016 20:53:26 +0100 (CET) Date: Sun, 30 Oct 2016 20:53:26 +0100 From: Mark Wielaard To: Jim Meyering Cc: Ian Lance Taylor , Jason Merrill , Eric Gallager , Manuel =?iso-8859-1?B?TPNwZXotSWLh8WV6?= , GCC Patches , Paolo Bonzini , Diego Novillo , Le-Chun Wu , Joseph Myers Subject: Re: [PATCH] Add -Wshadow-local and -Wshadow-compatible-local. Message-ID: <20161030195326.GH10081@stream> References: <1473598955-9246-1-git-send-email-mjw@redhat.com> <669d316c-b2a2-b511-8868-783e98783479@gmail.com> <1473841857.27552.264.camel@redhat.com> <1473857397.27552.280.camel@redhat.com> <20161024235709.GA10081@stream> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20161024235709.GA10081@stream> User-Agent: Mutt/1.7.1 (2016-10-04) On Tue, Oct 25, 2016 at 01:57:09AM +0200, Mark Wielaard wrote: > I think the only thing "blocking" the patch from going in is that > nobody made a decission on how the actual warning option should be > named. I think the suggestion for -Wshadow=[global|local|compatible-local] > is the right one. With -Wshadow being an alias for -Wshadow=global. > But since there are already gcc versions out there that accept > -Wshadow-local and -Wshadow-compatible-local (and you can find some > configure scripts that already check for those options) it would be > good to have those as (hidden) aliases. > > If people, some maintainer, agrees with that then we can do the .opt > file hacking to make it so. Nobody objected, nor did anybody say this is a great idea. But I think it is. So I just implemented the options this way. I made one small diagnostic change to fix a regression pointed out by gcc/testsuite/gcc.dg/pr48062.c. It should still be possible to ignore all shadow warnings with #pragma GCC diagnostic ignored "-Wshadow" when -Wshadow was given, but not the new -Wshadow=(local|compatible-local). So we now set warning_code = OPT_Wshadow when -Wshadow was given. The documentation and code comments were updated to refer to the new -Wshadow=... variants. OK to commit the attached patch? Thanks, Mark From 390697e924926d7f8e451d39114de4903db07325 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 11 Sep 2016 14:20:33 +0200 Subject: [PATCH] Add -Wshadow=global -Wshadow=local and -Wshadow=compatible-local. This patch from Le-Chun Wu adds two new shadow warning flags for C and C++: -Wshadow=local which warns if a local variable shadows another local variable or parameter, -Wshadow=compatible-local which warns if a local variable shadows another local variable or parameter whose type is compatible with that of the shadowing variable. It is already on the google/main branch (Google ref 39127) and was previously submitted by Diego Novillo and reviewed on http://codereview.appspot.com/4452058 I addressed the review comments and made the following changes: - Add -Wshadow=global (the default alias for -Wshadow). - Make the documented options -Wshadow=global, -Wshadow=local and -Wshadow=compatible-local (with hidden undocumented aliases -Wshadow-local and -Wshadow-compatible-local for compatibility). - The -Wshadow=global, -Wshadow=local and -Wshadow=compatible-local relationships are expressed in common.opt instead of in opts.c and documented in invoke.texi. - The "previous declaration" warnings were turned into notes and use the (now) existing infrastructure instead of duplicating the warnings. The testcases have been adjusted to expect the notes. - The conditional change in name-lookup.c for non-locals (where we don't want to change the warnings, but just check the global ones) has been dropped. - Use warning_at in c-decl.c (warn_if_shadowing). gcc/ChangeLog: 2016-10-30 Le-Chun Wu Mark Wielaard * doc/invoke.texi: Document Wshadow-local and Wshadow-compatible-local. * common.opt (Wshadow=global): New option. Default for -Wshadow. (Wshadow=local): New option. (Wshadow-local): Hidden alias for -Wshadow=local. (Wshadow=compatible-local): New option. (Wshadow-compatible-local): Hidden alias for -Wshadow=compatible-local. * doc/invoke.texi: Document Wshadow=global, Wshadow=local and Wshadow=compatible-local. gcc/c/ChangeLog: 2016-10-30 Le-Chun Wu Mark Wielaard * c-decl.c (warn_if_shadowing): Use the warning code corresponding to the given -Wshadow= variant. Use warning_at. gcc/cp/ChangeLog: 2016-10-30 Le-Chun Wu Mark Wielaard * name-lookup.c (pushdecl_maybe_friend): When emitting a shadowing warning, use the code corresponding to the given -Wshadow= variant. gcc/testsuite/ChangeLog 2016-10-30 Le-Chun Wu Mark Wielaard * gcc.dg/Wshadow-compatible-local-1.c: New test. * gcc.dg/Wshadow-local-1.c: Likewise. * gcc.dg/Wshadow-local-2.c: Likewise. * g++.dg/warn/Wshadow-compatible-local-1.C: Likewise. * g++.dg/warn/Wshadow-local-1.C: Likewise. * g++.dg/warn/Wshadow-local-2.C: Likewise. diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 136f304..3e1b7a4 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2735,7 +2735,9 @@ warn_if_shadowing (tree new_decl) struct c_binding *b; /* Shadow warnings wanted? */ - if (!warn_shadow + if (!(warn_shadow + || warn_shadow_local + || warn_shadow_compatible_local) /* No shadow warnings for internally generated vars. */ || DECL_IS_BUILTIN (new_decl) /* No shadow warnings for vars made for inlining. */ @@ -2759,9 +2761,23 @@ warn_if_shadowing (tree new_decl) break; } else if (TREE_CODE (old_decl) == PARM_DECL) - warned = warning (OPT_Wshadow, - "declaration of %q+D shadows a parameter", - new_decl); + { + enum opt_code warning_code; + + /* If '-Wshadow=compatible-local' is specified without other + -Wshadow= flags, we will warn only when the types of the + shadowing variable (i.e. new_decl) and the shadowed variable + (old_decl) are compatible. */ + if (warn_shadow) + warning_code = OPT_Wshadow; + else if (comptypes (TREE_TYPE (old_decl), TREE_TYPE (new_decl))) + warning_code = OPT_Wshadow_compatible_local; + else + warning_code = OPT_Wshadow_local; + warned = warning_at (DECL_SOURCE_LOCATION (new_decl), warning_code, + "declaration of %qD shadows a parameter", + new_decl); + } else if (DECL_FILE_SCOPE_P (old_decl)) { /* Do not warn if a variable shadows a function, unless @@ -2784,8 +2800,23 @@ warn_if_shadowing (tree new_decl) break; } else - warned = warning (OPT_Wshadow, "declaration of %q+D shadows a " - "previous local", new_decl); + { + enum opt_code warning_code; + + /* If '-Wshadow=compatible-local' is specified without other + -Wshadow= flags, we will warn only when the types of the + shadowing variable (i.e. new_decl) and the shadowed variable + (old_decl) are compatible. */ + if (warn_shadow) + warning_code = OPT_Wshadow; + else if (comptypes (TREE_TYPE (old_decl), TREE_TYPE (new_decl))) + warning_code = OPT_Wshadow_compatible_local; + else + warning_code = OPT_Wshadow_local; + warned = warning_at (DECL_SOURCE_LOCATION (new_decl), warning_code, + "declaration of %qD shadows a previous local", + new_decl); + } if (warned) inform (DECL_SOURCE_LOCATION (old_decl), diff --git a/gcc/common.opt b/gcc/common.opt index 20dbfc1..2c2f7ad 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -668,7 +668,25 @@ Warn about returning a pointer/reference to a local or temporary variable. Wshadow Common Var(warn_shadow) Warning -Warn when one local variable shadows another. +Warn when one variable shadows another. Same as -Wshadow=global. + +Wshadow=global +Common Warning Alias(Wshadow) +Warn when one variable shadows another (globally). + +Wshadow=local +Common Var(warn_shadow_local) Warning EnabledBy(Wshadow) +Warn when one local variable shadows another local variable or parameter. + +Wshadow-local +Common Warning Undocumented Alias(Wshadow=local) + +Wshadow=compatible-local +Common Var(warn_shadow_compatible_local) Warning EnabledBy(Wshadow=local) +Warn when one local variable shadows another local variable or parameter of compatible type. + +Wshadow-compatible-local +Common Warning Undocumented Alias(Wshadow=compatible-local) Wstack-protector Common Var(warn_stack_protect) Warning diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 9e84a1b..023ed87 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1195,19 +1195,41 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend) nowarn = true; } - if (warn_shadow && !nowarn) + if ((warn_shadow + || warn_shadow_local + || warn_shadow_compatible_local) + && !nowarn) { bool warned; + enum opt_code warning_code; + /* If '-Wshadow=compatible-local' is specified without other + -Wshadow= flags, we will warn only when the type of the + shadowing variable (i.e. x) can be converted to that of + the shadowed parameter (oldlocal). The reason why we only + check if x's type can be converted to oldlocal's type + (but not the other way around) is because when users + accidentally shadow a parameter, more than often they + would use the variable thinking (mistakenly) it's still + the parameter. It would be rare that users would use the + variable in the place that expects the parameter but + thinking it's a new decl. */ + if (warn_shadow) + warning_code = OPT_Wshadow; + else if (can_convert (TREE_TYPE (oldlocal), TREE_TYPE (x), + tf_none)) + warning_code = OPT_Wshadow_compatible_local; + else + warning_code = OPT_Wshadow_local; if (TREE_CODE (oldlocal) == PARM_DECL) - warned = warning_at (input_location, OPT_Wshadow, + warned = warning_at (input_location, warning_code, "declaration of %q#D shadows a parameter", x); else if (is_capture_proxy (oldlocal)) - warned = warning_at (input_location, OPT_Wshadow, + warned = warning_at (input_location, warning_code, "declaration of %qD shadows a lambda capture", x); else - warned = warning_at (input_location, OPT_Wshadow, + warned = warning_at (input_location, warning_code, "declaration of %qD shadows a previous local", x); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 242eed7..fd783bf 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -293,6 +293,7 @@ Objective-C and Objective-C++ Dialects}. -Wpointer-arith -Wno-pointer-to-int-cast @gol -Wno-pragmas -Wredundant-decls -Wno-return-local-addr @gol -Wreturn-type -Wsequence-point -Wshadow -Wno-shadow-ivar @gol +-Wshadow=global, -Wshadow=local, -Wshadow=compatible-local @gol -Wshift-overflow -Wshift-overflow=@var{n} @gol -Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value @gol -Wsign-compare -Wsign-conversion -Wfloat-conversion @gol @@ -5321,6 +5322,7 @@ variable, parameter, type, class member (in C++), or instance variable (in Objective-C) or whenever a built-in function is shadowed. Note that in C++, the compiler warns if a local variable shadows an explicit typedef, but not if it shadows a struct/class/enum. +Same as @option{-Wshadow=global}. @item -Wno-shadow-ivar @r{(Objective-C only)} @opindex Wno-shadow-ivar @@ -5328,6 +5330,48 @@ explicit typedef, but not if it shadows a struct/class/enum. Do not warn whenever a local variable shadows an instance variable in an Objective-C method. +@item -Wshadow=global +@opindex Wshadow=local +The default for @option{-Wshadow}. Warns for any (global) shadowing. + +@item -Wshadow=local +@opindex Wshadow=local +Warn when a local variable shadows another local variable or parameter. +This warning is enabled by @option{-Wshadow=global}. + +@item -Wshadow=compatible-local +@opindex Wshadow=compatible-local +Warn when a local variable shadows another local variable or parameter +whose type is compatible with that of the shadowing variable. In C++, +type compatibility here means the type of the shadowing variable can be +converted to that of the shadowed variable. The creation of this flag +(in addition to @option{-Wshadow=local}) is based on the idea that when +a local variable shadows another one of incompatible type, it is most +likely intentional, not a bug or typo, as shown in the following example: + +@smallexample +@group +for (SomeIterator i = SomeObj.begin(); i != SomeObj.end(); ++i) +@{ + for (int i = 0; i < N; ++i) + @{ + ... + @} + ... +@} +@end group +@end smallexample + +Since the two variable @code{i} in the example above have incompatible types, +enabling only @option{-Wshadow=compatible-local} will not emit a warning. +Because their types are incompatible, if a programmer accidentally uses one +in place of the other, type checking will catch that and emit an error or +warning. So not warning (about shadowing) in this case will not lead to +undetected bugs. Use of this flag instead of @option{-Wshadow=local} can +possibly reduce the number of warnings triggered by intentional shadowing. + +This warning is enabled by @option{-Wshadow=local}. + @item -Wlarger-than=@var{len} @opindex Wlarger-than=@var{len} @opindex Wlarger-than-@var{len} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7ebc616..1847d22 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2016-10-30 Le-Chun Wu + Mark Wielaard + + * gcc.dg/Wshadow-compatible-local-1.c: New test. + * gcc.dg/Wshadow-local-1.c: Likewise. + * gcc.dg/Wshadow-local-2.c: Likewise. + * g++.dg/warn/Wshadow-compatible-local-1.C: Likewise. + * g++.dg/warn/Wshadow-local-1.C: Likewise. + * g++.dg/warn/Wshadow-local-2.C: Likewise. + + 2016-10-29 Jakub Jelinek PR rtl-optimization/77919 diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-compatible-local-1.C b/gcc/testsuite/g++.dg/warn/Wshadow-compatible-local-1.C new file mode 100644 index 0000000..aac6861 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wshadow-compatible-local-1.C @@ -0,0 +1,63 @@ +/* { dg-do compile } */ +/* { dg-options -Wshadow=compatible-local } */ + +class Bar { +}; + +class ChildBar : public Bar { +}; + +Bar bar; + +class Foo { + private: + int val; + + public: + int func1(int x) { + int val; + val = x; + return val; + } + + int func2(int i) { // { dg-message "note: shadowed declaration is here" } + int a = 3; // { dg-message "note: shadowed declaration is here" } + + for (int i = 0; i < 5; ++i) { // { dg-warning "shadows a parameter" } + for (int i = 0; i < 3; ++i) { // { dg-warning "shadows a previous local" } + int a = i; // { dg-warning "shadows a previous local" } + func1(a); + } + } + + return a; + } + + int func3() { + int bar; + float func1 = 0.3; + int f = 5; // { dg-message "note: shadowed declaration is here" } + + if (func1 > 1) { + float f = 2.0; // { dg-warning "shadows a previous local" } + bar = f; + } + else + bar = 1; + return bar; + } + + void func4() { + Bar *bar; // { dg-bogus "shadowed declaration" } + ChildBar *cbp; // { dg-bogus "shadowed declaration" } + Bar *bp; // { dg-message "note: shadowed declaration is here" } + if (val) { + int bar; // { dg-bogus "shadows a previous local" } + Bar *cbp; // { dg-bogus "shadows a previous local" } + ChildBar *bp; // { dg-warning "shadows a previous local" } + func1(bar); + } + } +}; + +// { dg-message "note: shadowed declaration" "" { target *-*-* } 26 } diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-local-1.C b/gcc/testsuite/g++.dg/warn/Wshadow-local-1.C new file mode 100644 index 0000000..dba6db5 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wshadow-local-1.C @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options -Wshadow=local } */ + +struct status +{ + int member; + void foo2 (); + + inline static int foo3 (int member) + { + return member; + } +}; + +int decl1; // { dg-bogus "shadowed declaration" } +int decl2; // { dg-bogus "shadowed declaration" } +void foo (struct status &status, + double decl1) // { dg-bogus "shadows a global" } +{ +} + +void foo1 (int d) +{ + double d; // { dg-error "shadows a parameter" } +} + +void status::foo2 () +{ + int member; // { dg-bogus "shadows a member" } + int decl2; // { dg-bogus "shadows a global" } + int local; // { dg-message "note: shadowed declaration is here" } + { + int local; // { dg-warning "shadows a previous local" } + } +} diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-local-2.C b/gcc/testsuite/g++.dg/warn/Wshadow-local-2.C new file mode 100644 index 0000000..fe42c89 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wshadow-local-2.C @@ -0,0 +1,63 @@ +/* { dg-do compile } */ +/* { dg-options -Wshadow=local } */ + +class Bar { +}; + +class ChildBar : public Bar { +}; + +Bar bar; // { dg-bogus "shadowed declaration" } + +class Foo { + private: + int val; + + public: + int func1(int x) { + int val; // { dg-bogus "shadows a member" } + val = x; + return val; + } + + int func2(int i) { // { dg-message "shadowed declaration is here" } + int a = 3; // { dg-message "shadowed declaration is here" } + + for (int i = 0; i < 5; ++i) { // { dg-warning "shadows a parameter" } + for (int i = 0; i < 3; ++i) { // { dg-warning "shadows a previous local" } + int a = i; // { dg-warning "shadows a previous local" } + func1(a); + } + } + + return a; + } + + int func3() { + int bar; // { dg-bogus "shadows a global" } + float func1 = 0.3; // { dg-bogus "shadows a member" } + int f = 5; // { dg-message "shadowed declaration is here" } + + if (func1 > 1) { + float f = 2.0; // { dg-warning "shadows a previous local" } + bar = f; + } + else + bar = 1; + return bar; + } + + void func4() { + Bar *bar; // { dg-message "shadowed declaration is here" } + ChildBar *cbp; // { dg-message "shadowed declaration is here" } + Bar *bp; // { dg-message "shadowed declaration is here" } + if (val) { + int bar; // { dg-warning "shadows a previous local" } + Bar *cbp; // { dg-warning "shadows a previous local" } + ChildBar *bp; // { dg-warning "shadows a previous local" } + func1(bar); + } + } +}; + +// { dg-message "shadowed declaration is here" "" { target *-*-* } 26 } diff --git a/gcc/testsuite/gcc.dg/Wshadow-compatible-local-1.c b/gcc/testsuite/gcc.dg/Wshadow-compatible-local-1.c new file mode 100644 index 0000000..ed7b2e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wshadow-compatible-local-1.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-Wshadow=compatible-local" } */ + +struct Bar { +}; + +struct Bar bar; /* { dg-bogus "shadowed declaration" } */ + +int val; /* { dg-bogus "shadowed declaration" } */ + +int func1(int x) { /* { dg-bogus "shadowed declaration" } */ + int val; /* { dg-bogus "shadows a global" } */ + val = x; + return val; +} + +int func2(int i) { + int a = 3; /* { dg-message "shadowed declaration" } */ + int j; /* { dg-message "shadowed declaration" } */ + + for (j = 0; j < i; ++j) { + int a = j; /* { dg-warning "shadows a previous local" } */ + int j = a + 1; /* { dg-warning "shadows a previous local" } */ + func1(j); + } + + return a; +} + +void func4() { + struct Bar bar; /* { dg-bogus "shadowed declaration" } */ + if (val) { + int bar; /* { dg-bogus "shadows a previous local" } */ + func1(bar); + } +} diff --git a/gcc/testsuite/gcc.dg/Wshadow-local-1.c b/gcc/testsuite/gcc.dg/Wshadow-local-1.c new file mode 100644 index 0000000..161f994 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wshadow-local-1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-Wshadow=local" } */ + +int decl1; /* should not warn */ +void foo (double decl1) /* should not warn */ +{ +} + +void foo2 (int d) /* { dg-message "shadowed declaration" } */ +{ + { + double d; /* { dg-warning "shadows a parameter" } */ + } +} + +void foo3 () +{ + int local; /* { dg-message "shadowed declaration" } */ + { + int local; /* { dg-warning "shadows a previous local" } */ + } +} diff --git a/gcc/testsuite/gcc.dg/Wshadow-local-2.c b/gcc/testsuite/gcc.dg/Wshadow-local-2.c new file mode 100644 index 0000000..8f6b132 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wshadow-local-2.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-options "-Wshadow=local" } */ + +struct Bar { +}; + +struct Bar bar; /* { dg-bogus "shadowed declaration" } */ + +int val; /* { dg-bogus "shadowed declaration" } */ + +int func1(int x) { /* { dg-bogus "shadowed declaration" } */ + int val; /* { dg-bogus "shadows a global" } */ + val = x; + return val; +} + +int func2(int i) { + int a = 3; /* { dg-message "shadowed declaration" } */ + int j; /* { dg-message "shadowed declaration" } */ + + for (j = 0; j < i; ++j) { + int a = j; /* { dg-warning "shadows a previous local" } */ + int j = a + 1; /* { dg-warning "shadows a previous local" } */ + func1(j); + } + + return a; +} + +int func3() { + int bar; /* { dg-bogus "shadows a global" } */ + float func1 = 0.3; /* { dg-bogus "shadows a global" } */ + + if (func1 > 1) + bar = 2; + else + bar = 1; + return bar; +} + +void func4() { + struct Bar bar; /* { dg-message "shadowed declaration" } */ + if (val) { + int bar; /* { dg-warning "shadows a previous local" } */ + func1(bar); + } +} + +/* { dg-bogus "shadows a global" "" { target *-*-* } 42 } */ diff --git a/gcc/testsuite/gcc.dg/Wshadow-local-3.c b/gcc/testsuite/gcc.dg/Wshadow-local-3.c new file mode 100644 index 0000000..429df37 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wshadow-local-3.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Wno-shadow" } */ + +void func() { + int i; + { + int i; /* should not warn */ + } +}