* cp/decl.c (shadow_warning): New function.
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Nov 2001 19:04:43 +0000 (19:04 +0000)
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Nov 2001 19:04:43 +0000 (19:04 +0000)
(pushdecl): Improve -Wshadow warnings.  Don't give both a warning
and an error when a block scope decl shadows a parameter.

* g++.dg/warn/Wshadow-1.C: New tests.
* g++.old-deja/g++.mike/for3.C: Update.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46852 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wshadow-1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.mike/for3.C

index d442d11..b410b51 100644 (file)
@@ -1,3 +1,9 @@
+2001-11-08  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * cp/decl.c (shadow_warning): New function.
+       (pushdecl): Improve -Wshadow warnings.  Don't give both a warning
+       and an error when a block scope decl shadows a parameter.
+
 2001-11-08  Richard Henderson  <rth@redhat.com>
 
        * config/fp-bit.h (usi_to_float): Define for US_SOFTWARE_GOFAST
index 1b3fc9e..a210a7b 100644 (file)
@@ -147,6 +147,7 @@ static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
 static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
 static void store_parm_decls PARAMS ((tree));
 static int cp_missing_noreturn_ok_p PARAMS ((tree));
+static void shadow_warning PARAMS ((const char *, tree, tree));
 
 #if defined (DEBUG_CP_BINDING_LEVELS)
 static void indent PARAMS ((void));
@@ -3788,6 +3789,20 @@ duplicate_decls (newdecl, olddecl)
   return 1;
 }
 
+/* Output a -Wshadow warning MSGID, if non-NULL, and give the location
+   of the previous declaration.  */
+static void
+shadow_warning (msgid, name, decl)
+     const char *msgid;
+     tree name, decl;
+{
+  warning ("declaration of `%s' shadows %s", IDENTIFIER_POINTER (name), msgid);
+  warning_with_file_and_line (DECL_SOURCE_FILE (decl),
+                             DECL_SOURCE_LINE (decl),
+                             "shadowed declaration is here");
+}
+
+
 /* Record a decl-node X as belonging to the current lexical scope.
    Check for errors (such as an incompatible declaration for the same
    name already seen in the same scope).
@@ -4173,47 +4188,53 @@ pushdecl (x)
          if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
              /* Inline decls shadow nothing.  */
              && !DECL_FROM_INLINE (x)
-             && TREE_CODE (oldlocal) == PARM_DECL
-             /* Don't complain if it's from an enclosing function.  */
-             && DECL_CONTEXT (oldlocal) == current_function_decl
-             && TREE_CODE (x) != PARM_DECL)
+             && TREE_CODE (oldlocal) == PARM_DECL)
            {
-             /* Go to where the parms should be and see if we
-                find them there.  */
-             struct binding_level *b = current_binding_level->level_chain;
+             bool err = false;
 
-             if (cleanup_label)
-               b = b->level_chain;
+             /* Don't complain if it's from an enclosing function.  */
+             if (DECL_CONTEXT (oldlocal) == current_function_decl
+                 && TREE_CODE (x) != PARM_DECL)
+               {
+                 /* Go to where the parms should be and see if we find
+                    them there.  */
+                 struct binding_level *b = current_binding_level->level_chain;
 
-             /* ARM $8.3 */
-             if (b->parm_flag == 1)
-               cp_error ("declaration of `%#D' shadows a parameter", name);
+                 if (cleanup_label)
+                   b = b->level_chain;
+
+                 /* ARM $8.3 */
+                 if (b->parm_flag == 1)
+                   {
+                     cp_error ("declaration of `%#D' shadows a parameter",
+                               name);
+                     err = true;
+                   }
+               }
+
+             if (warn_shadow && !err)
+               shadow_warning ("a parameter", name, oldlocal);
            }
 
          /* Maybe warn if shadowing something else.  */
-         if (warn_shadow && !DECL_EXTERNAL (x)
-             /* Inline decls shadow nothing.  */
-             && !DECL_FROM_INLINE (x)
+         else if (warn_shadow && !DECL_EXTERNAL (x)
              /* No shadow warnings for internally generated vars.  */
              && ! DECL_ARTIFICIAL (x)
              /* No shadow warnings for vars made for inlining.  */
              && ! DECL_FROM_INLINE (x))
            {
-             if (oldlocal != NULL_TREE && TREE_CODE (oldlocal) == PARM_DECL)
-               warning ("declaration of `%s' shadows a parameter",
-                       IDENTIFIER_POINTER (name));
-             else if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE
+             if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE
                       && current_class_ptr
                       && !TREE_STATIC (name))
-               warning ("declaration of `%s' shadows a member of `this'",
-                       IDENTIFIER_POINTER (name));
-             else if (oldlocal != NULL_TREE)
-               warning ("declaration of `%s' shadows previous local",
-                       IDENTIFIER_POINTER (name));
-             else if (oldglobal != NULL_TREE)
+               cp_warning ("declaration of `%s' shadows a member of `this'",
+                           IDENTIFIER_POINTER (name));
+             else if (oldlocal != NULL_TREE
+                      && TREE_CODE (oldlocal) == VAR_DECL)
+               shadow_warning ("a previous local", name, oldlocal);
+             else if (oldglobal != NULL_TREE
+                      && TREE_CODE (oldglobal) == VAR_DECL)
                /* XXX shadow warnings in outer-more namespaces */
-               warning ("declaration of `%s' shadows global declaration",
-                       IDENTIFIER_POINTER (name));
+               shadow_warning ("a global declaration", name, oldglobal);
            }
        }
 
index d11a53d..cd31ce7 100644 (file)
@@ -1,3 +1,8 @@
+2001-11-08  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * g++.dg/warn/Wshadow-1.C: New tests.
+       * g++.old-deja/g++.mike/for3.C: Update.
+
 2001-11-06  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * gcc.dg/c90-array-lval-1.c, gcc.dg/c90-array-lval-2.c,
diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-1.C b/gcc/testsuite/g++.dg/warn/Wshadow-1.C
new file mode 100644 (file)
index 0000000..b7d95e5
--- /dev/null
@@ -0,0 +1,42 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.  */
+
+/* { dg-do compile } */
+/* { dg-options -Wshadow } */
+
+/* Source: Neil Booth, 3 Nov 2001, and PR 16, 713.  -Wshadow was
+   giving a bunch of warnings we didn't want, and wasn't giving the
+   location of the shadowed variable.  */
+
+struct status                  // { dg-bogus "shadowed declaration" }
+{
+  int member;
+  void foo2 ();
+
+  inline static int foo3 (int member) // { dg-bogus "shadows" }
+  {
+    return member;
+  }
+};
+
+int decl1;                     // { dg-warning "shadowed declaration" }
+int decl2;                     // { dg-warning "shadowed declaration" }
+void foo (struct status &status,// { dg-bogus "shadows a global decl" }
+         double decl1)
+{                              // { dg-warning "shadows a global decl" }
+}
+
+void foo1 (int d)
+{
+  double d;                    // { dg-error "shadows a parameter" }
+}
+
+// { dg-error "In member function" "ignored" { target *-*-* } 0 }
+void status::foo2 ()
+{
+  int member;                  // { dg-warning "shadows a member" }
+  int decl2;                   // { dg-warning "shadows a global decl" }
+  int local;                   // { dg-warning "shadowed declaration" }
+  {
+    int local;                 // { dg-warning "shadows a previous local" }
+  }
+}
index a8276a4..7e88d7e 100644 (file)
@@ -1,9 +1,9 @@
 // Special g++ Options: -Wshadow
 
 int
-main(int i) {
-  for(int i=1; i < 3; i++);    // WARNING - shadows parm
-  for(int i=1; i < 3; i++);    // WARNING - shadows parm
+main(int i) {                  // WARNING - shadowed decl
+  for(int i=1; i < 3; i++);    // WARNING - declaration of
+  for(int i=1; i < 3; i++);    // WARNING - declaration of
   for(int j=1; j < 3; j++);
   for(int j=1; j < 3; j++);
 }