[patch] fix PR/44128 (C++ not warn on type decl shadowing with -Wshadow)

Le-Chun Wu lcwu@google.com
Sat Jun 5 01:31:00 GMT 2010


On Thu, May 27, 2010 at 12:02 PM, Jason Merrill <jason@redhat.com> wrote:
> Sorry, thought I had responded to this already.

Sorry for my delay in responding to your response. (Been sidetracked
by other stuff.)

>
> Why only warn if the TREE_CODE happens to match?  I think we might as well
> also warn if, for instance, a typedef shadows a variable.
>

The current implementation (before my change) already warns if a
typedef shadows a variable. What it doesn't warn is if a local
variable shadows a typedef. And this behavior appears to be by design
(based on PR/16). The rationale provided in PR/16 is that when a local
variable shadows a previously-declared struct/class/enum name, it's
probably not accidental but intentional, and therefore the compiler
should not warn about it.

What this patch tries to do is for the compiler to warn if a type
declaration shadows another type declaration, or a local struct
shadows another struct, etc. (That's why we check if the new decl and
the old decl have the same TREE_CODE.) These cases are most likely
bugs/typos instead of intentional.

Attached please find the latest patch with the updated source tree. I
also modified the -Wshadow documentation for the new behavior. Please
let me know if you have any other comments. Thanks,

Le-chun

2010-06-04  Le-Chun Wu  <lcwu@google.com>

        PR/44128
        * gcc/doc/invoke.texi: Update documentation of -Wshadow.
        * gcc/cp/name-lookup.c (pushdecl_maybe_friend): Warn when a local decl
        shadows another local or global decl if both decls have the same
        TREE_CODE.
        * gcc/testsuite/g++.dg/warn/Wshadow-7.C: New test.

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi (revision 159995)
+++ gcc/doc/invoke.texi (working copy)
@@ -3834,8 +3834,10 @@ Do not warn whenever an @samp{#else} or
 @item -Wshadow
 @opindex Wshadow
 @opindex Wno-shadow
-Warn whenever a local variable shadows another local variable, parameter or
-global variable or whenever a built-in function is shadowed.
+Warn whenever a local variable shadows another local variable, parameter,
+global variable, or a class member (in C++) or whenever a built-in function
+is shadowed, or whenever a local declaration (e.g. a type declaration)
+shadows another local or global declaration of the same type.

 @item -Wlarger-than=@var{len}
 @opindex Wlarger-than=@var{len}
Index: gcc/testsuite/g++.dg/warn/Wshadow-7.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wshadow-7.C       (revision 0)
+++ gcc/testsuite/g++.dg/warn/Wshadow-7.C       (revision 0)
@@ -0,0 +1,12 @@
+// PR c++/44128
+// { dg-options "-Wshadow" }
+
+typedef long My_ssize_t;  // { dg-warning "shadowed declaration" }
+
+void bar() {
+  typedef int My_ssize_t; // { dg-warning "shadows a global" }
+  typedef char My_Num;    // { dg-warning "shadowed declaration" }
+  {
+    typedef short My_Num; // { dg-warning "shadows a previous local" }
+  }
+}
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c        (revision 159995)
+++ gcc/cp/name-lookup.c        (working copy)
@@ -1017,7 +1017,8 @@ pushdecl_maybe_friend (tree x, bool is_f
                   /* Inline decls shadow nothing.  */
                   && !DECL_FROM_INLINE (x)
                   && (TREE_CODE (oldlocal) == PARM_DECL
-                      || TREE_CODE (oldlocal) == VAR_DECL)
+                      || TREE_CODE (oldlocal) == VAR_DECL
+                       || TREE_CODE (oldlocal) == TREE_CODE (x))
                   /* Don't check the `this' parameter.  */
                   && !DECL_ARTIFICIAL (oldlocal)
                   && !DECL_ARTIFICIAL (x))
@@ -1103,7 +1104,8 @@ pushdecl_maybe_friend (tree x, bool is_f
                           x);
                }
              else if (oldglobal != NULL_TREE
-                      && TREE_CODE (oldglobal) == VAR_DECL)
+                      && (TREE_CODE (oldglobal) == VAR_DECL
+                           || TREE_CODE (oldglobal) == TREE_CODE (x)))
                /* XXX shadow warnings in outer-more namespaces */
                {
                  warning_at (input_location, OPT_Wshadow,



More information about the Gcc-patches mailing list