From 84ff4775d41b716c1b862d4d91ff69127686b668 Mon Sep 17 00:00:00 2001 From: Le-Chun Wu Date: Mon, 31 Oct 2016 13:21:59 +0000 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. Co-Authored-By: Mark Wielaard From-SVN: r241699 --- gcc/ChangeLog | 12 ++++ gcc/c/ChangeLog | 6 ++ gcc/c/c-decl.c | 43 +++++++++++-- gcc/common.opt | 20 +++++- gcc/cp/ChangeLog | 7 +++ gcc/cp/name-lookup.c | 30 +++++++-- gcc/doc/invoke.texi | 44 +++++++++++++ gcc/testsuite/ChangeLog | 11 ++++ .../g++.dg/warn/Wshadow-compatible-local-1.C | 63 +++++++++++++++++++ gcc/testsuite/g++.dg/warn/Wshadow-local-1.C | 35 +++++++++++ gcc/testsuite/g++.dg/warn/Wshadow-local-2.C | 63 +++++++++++++++++++ .../gcc.dg/Wshadow-compatible-local-1.c | 36 +++++++++++ gcc/testsuite/gcc.dg/Wshadow-local-1.c | 22 +++++++ gcc/testsuite/gcc.dg/Wshadow-local-2.c | 49 +++++++++++++++ gcc/testsuite/gcc.dg/Wshadow-local-3.c | 9 +++ 15 files changed, 439 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wshadow-compatible-local-1.C create mode 100644 gcc/testsuite/g++.dg/warn/Wshadow-local-1.C create mode 100644 gcc/testsuite/g++.dg/warn/Wshadow-local-2.C create mode 100644 gcc/testsuite/gcc.dg/Wshadow-compatible-local-1.c create mode 100644 gcc/testsuite/gcc.dg/Wshadow-local-1.c create mode 100644 gcc/testsuite/gcc.dg/Wshadow-local-2.c create mode 100644 gcc/testsuite/gcc.dg/Wshadow-local-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ddd004900b8..7905d955cfe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2016-09-11 Le-Chun Wu + Mark Wielaard + + * 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. + 2016-10-31 Bin Cheng * tree-vect-slp.c (vect_get_and_check_slp_defs): New parameter SWAP. diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 725afcfefa0..ee50c304b5f 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2016-09-11 Le-Chun Wu + Mark Wielaard + + * c-decl.c (warn_if_shadowing): Use the warning code corresponding + to the given -Wshadow= variant. + 2016-10-13 Thomas Preud'homme * c-typeck.c: Include memmodel.h. diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 136f304ca30..3e1b7a4016b 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 20dbfc1d6a1..2c2f7ad7aa9 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/ChangeLog b/gcc/cp/ChangeLog index efce361f880..be439ec3a38 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-09-11 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. + 2016-10-26 Jason Merrill * class.c (add_method): Allow using-declarations to coexist. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 9e84a1b1f2e..023ed87098f 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 242eed7df34..fd783bf862d 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 051ae832696..5e773fb47a4 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-30 Bill Schmidt PR tree-optimization/71915 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 00000000000..aac68619c3a --- /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 00000000000..dba6db5d1c2 --- /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 00000000000..fe42c89d242 --- /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 00000000000..ed7b2e45ef1 --- /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 00000000000..161f9941fb6 --- /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 00000000000..8f6b132f66d --- /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 00000000000..429df37f541 --- /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 */ + } +} -- 2.30.2