c-common.c (shadow_warning): New function, moved from cp/decl.c.
authorNeil Booth <neil@daikokuya.demon.co.uk>
Wed, 5 Dec 2001 23:20:00 +0000 (23:20 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Wed, 5 Dec 2001 23:20:00 +0000 (23:20 +0000)
* c-common.c (shadow_warning): New function, moved from cp/decl.c.
* c-common.h (shadow_warning): New.
* c-decl.c: Include c-common.h.
(warn_if_shadowing): New, broken out of pushdecl.
(pushdecl): Use warn_if_shadowing.
(store_parm_decls): Prevent duplicate -Wshadow warnings.
cp:
* decl.c: Include c-common.h.
(shadow_warning): Move to c-common.c.
testsuite:
* gcc.dg/Wshadow-1.c: New test.

From-SVN: r47701

gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wshadow-1.c [new file with mode: 0644]

index a813ffcc56e3f031b03e11e2b1ebc59e0b056302..941d79568fa778f83ac1d286a2d9a0e0d2ca9af6 100644 (file)
@@ -1,3 +1,12 @@
+2001-12-05  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * c-common.c (shadow_warning): New function, moved from cp/decl.c.
+       * c-common.h (shadow_warning): New.
+       * c-decl.c: Include c-common.h.
+       (warn_if_shadowing): New, broken out of pushdecl.
+       (pushdecl): Use warn_if_shadowing.
+       (store_parm_decls): Prevent duplicate -Wshadow warnings.
+
 Wed Dec  5 17:59:19 2001  Douglas B. Rupp  <rupp@gnat.com>
 
        * config/alpha/vms.h (SIZE_TYPE, PTRDIFF_TYPE): Remove, were disabled.
index f5fc0d348f5ded7b92610fa0a07bacb9e908bfbb..29bb05948c1bda1f732e7ea24835d8c51ce9bf64 100644 (file)
@@ -4017,3 +4017,17 @@ c_common_insert_default_attributes (decl)
 #undef DEF_ATTR_TREE_LIST
 #undef DEF_FN_ATTR
 }
+
+/* Output a -Wshadow warning MSGID about NAME, an IDENTIFIER_NODE, and
+   additionally give the location of the previous declaration DECL.  */
+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");
+}
+
index 4ab415c1f1e922f55ab59683f53734c7803c98b3..33835f653db4723af95c7f48010a5d01e4d34c20 100644 (file)
@@ -330,6 +330,8 @@ extern tree walk_stmt_tree                  PARAMS ((tree *,
 extern void prep_stmt                           PARAMS ((tree));
 extern void expand_stmt                         PARAMS ((tree));
 extern void mark_stmt_tree                      PARAMS ((void *));
+extern void shadow_warning                     PARAMS ((const char *,
+                                                        tree, tree));
 
 /* Extra information associated with a DECL.  Other C dialects extend
    this structure in various ways.  The C front-end only uses this
index 5471f6b268e5b44628a1ece3bdcc2b33c5f0c673..fb1d8e8653dc6ebad9324d1208c0388486dc5bec 100644 (file)
@@ -45,6 +45,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "target.h"
 #include "debug.h"
 #include "timevar.h"
+#include "c-common.h"
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -280,6 +281,7 @@ static tree grokparms                       PARAMS ((tree, int));
 static void layout_array_type          PARAMS ((tree));
 static tree c_make_fname_decl           PARAMS ((tree, int));
 static void c_expand_body               PARAMS ((tree, int, int));
+static void warn_if_shadowing          PARAMS ((tree, tree));
 \f
 /* C-specific option variables.  */
 
@@ -2047,6 +2049,66 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
   return 1;
 }
 
+/* Check whether decl-node X shadows an existing declaration.
+   OLDLOCAL is the old IDENTIFIER_LOCAL_VALUE of the DECL_NAME of X,
+   which might be a NULL_TREE.  */
+static void
+warn_if_shadowing (x, oldlocal)
+     tree x, oldlocal;
+{
+  tree name;
+
+  if (DECL_EXTERNAL (x))
+    return;
+
+  name = DECL_NAME (x);
+
+  /* Warn if shadowing an argument at the top level of the body.  */
+  if (oldlocal != 0
+      /* This warning doesn't apply to the parms of a nested fcn.  */
+      && ! current_binding_level->parm_flag
+      /* Check that this is one level down from the parms.  */
+      && current_binding_level->level_chain->parm_flag
+      /* Check that the decl being shadowed
+        comes from the parm level, one level up.  */
+      && chain_member (oldlocal, current_binding_level->level_chain->names))
+    {
+      if (TREE_CODE (oldlocal) == PARM_DECL)
+       pedwarn ("declaration of `%s' shadows a parameter",
+                IDENTIFIER_POINTER (name));
+      else
+       pedwarn ("declaration of `%s' shadows a symbol from the parameter list",
+                IDENTIFIER_POINTER (name));
+    }
+  /* Maybe warn if shadowing something else.  */
+  else if (warn_shadow
+          /* No shadow warnings for internally generated vars.  */
+          && DECL_SOURCE_LINE (x) != 0
+          /* No shadow warnings for vars made for inlining.  */
+          && ! DECL_FROM_INLINE (x))
+    {
+      if (TREE_CODE (x) == PARM_DECL
+         && current_binding_level->level_chain->parm_flag)
+       /* Don't warn about the parm names in function declarator
+          within a function declarator.
+          It would be nice to avoid warning in any function
+          declarator in a declaration, as opposed to a definition,
+          but there is no way to tell it's not a definition.  */
+       ;
+      else if (oldlocal)
+       {
+         if (TREE_CODE (oldlocal) == PARM_DECL)
+           shadow_warning ("a parameter", name, oldlocal);
+         else
+           shadow_warning ("a previous local", name, oldlocal);
+       }
+      else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
+              && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
+       shadow_warning ("a global declaration", name,
+                       IDENTIFIER_GLOBAL_VALUE (name));
+    }
+}
+
 /* 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).
@@ -2431,49 +2493,7 @@ pushdecl (x)
                IDENTIFIER_LIMBO_VALUE (name) = x;
            }
 
-         /* Warn if shadowing an argument at the top level of the body.  */
-         if (oldlocal != 0 && !DECL_EXTERNAL (x)
-             /* This warning doesn't apply to the parms of a nested fcn.  */
-             && ! current_binding_level->parm_flag
-             /* Check that this is one level down from the parms.  */
-             && current_binding_level->level_chain->parm_flag
-             /* Check that the decl being shadowed
-                comes from the parm level, one level up.  */
-             && chain_member (oldlocal, current_binding_level->level_chain->names))
-           {
-             if (TREE_CODE (oldlocal) == PARM_DECL)
-               pedwarn ("declaration of `%s' shadows a parameter",
-                        IDENTIFIER_POINTER (name));
-             else
-               pedwarn ("declaration of `%s' shadows a symbol from the parameter list",
-                        IDENTIFIER_POINTER (name));
-           }
-
-         /* Maybe warn if shadowing something else.  */
-         else if (warn_shadow && !DECL_EXTERNAL (x)
-                  /* No shadow warnings for internally generated vars.  */
-                  && DECL_SOURCE_LINE (x) != 0
-                  /* No shadow warnings for vars made for inlining.  */
-                  && ! DECL_FROM_INLINE (x))
-           {
-             const char *id = IDENTIFIER_POINTER (name);
-
-             if (TREE_CODE (x) == PARM_DECL
-                 && current_binding_level->level_chain->parm_flag)
-               /* Don't warn about the parm names in function declarator
-                  within a function declarator.
-                  It would be nice to avoid warning in any function
-                  declarator in a declaration, as opposed to a definition,
-                  but there is no way to tell it's not a definition.  */
-               ;
-             else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL)
-               warning ("declaration of `%s' shadows a parameter", id);
-             else if (oldlocal != 0)
-               warning ("declaration of `%s' shadows previous local", id);
-             else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
-                      && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
-               warning ("declaration of `%s' shadows global declaration", id);
-           }
+         warn_if_shadowing (x, oldlocal);
 
          /* If storing a local value, there may already be one (inherited).
             If so, record it for restoration when this binding level ends.  */
@@ -6354,11 +6374,16 @@ store_parm_decls ()
      then CONST_DECLs for foo and bar are put here.  */
   tree nonparms = 0;
 
+  /* The function containing FNDECL, if any.  */
+  tree context = decl_function_context (fndecl);
+
   /* Nonzero if this definition is written with a prototype.  */
   int prototype = 0;
 
-  /* The function containing FNDECL, if any.  */
-  tree context = decl_function_context (fndecl);
+  int saved_warn_shadow = warn_shadow;
+
+  /* Don't re-emit shadow warnings.  */
+  warn_shadow = 0;
 
   if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST)
     {
@@ -6758,6 +6783,8 @@ store_parm_decls ()
      not safe to try to expand expressions involving them.  */
   immediate_size_expand = 0;
   cfun->x_dont_save_pending_sizes_p = 1;
+
+  warn_shadow = saved_warn_shadow;
 }
 \f
 /* Finish up a function declaration and compile that function
index b01f868c7a89e261196bf48fe40832243b7eb66d..a0a3f49fb14de418f6651fdf396954cebdeed51a 100644 (file)
@@ -1,3 +1,8 @@
+2001-12-05  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * decl.c: Include c-common.h.
+       (shadow_warning): Move to c-common.c.
+
 Wed Dec  5 17:00:49 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * decl.c (duplicate_decls): Don't copy DECL_NO_CHECK_MEMORY_USAGE.
index 3916610a310d832bddde63e570b779ba705ec247..2df8b229182227ec3aae3ceb4dc9677eb973422a 100644 (file)
@@ -45,6 +45,7 @@ Boston, MA 02111-1307, USA.  */
 #include "ggc.h"
 #include "tm_p.h"
 #include "target.h"
+#include "c-common.h"
 
 extern const struct attribute_spec *lang_attribute_table;
 
@@ -147,7 +148,6 @@ 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));
@@ -3787,20 +3787,6 @@ 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).
index 95b055cb7a1304db5af0c5a3ab6f38fee3dea9c7..3e9d657510ecad194df8621520231178d3de125b 100644 (file)
@@ -1,3 +1,7 @@
+2001-12-05  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * gcc.dg/Wshadow-1.c: New test.
+
 2001-12-05  Jakub Jelinek  <jakub@redhat.com>
 
        * gcc.c-torture/compile/20011130-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/Wshadow-1.c b/gcc/testsuite/gcc.dg/Wshadow-1.c
new file mode 100644 (file)
index 0000000..63808aa
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.  */
+
+/* { dg-do compile } */
+/* { dg-options "-Wshadow -pedantic-errors" } */
+
+/* Source: Neil Booth, 5 Dec 2001.  */
+
+int decl1;                     /* { dg-warning "shadowed declaration" } */
+void foo (double decl1)                /* { dg-warning "shadows a global decl" } */
+{                              
+}
+
+void foo1 (int d)
+{
+  double d;     /* { dg-bogus "warning" "warning in place of error" } */
+  /* { dg-error "shadows a parameter" "" { target *-*-* } 15 } */
+}
+
+void foo2 (int d)              /* { dg-warning "shadowed declaration" } */
+{
+  {
+    double d;                  /* { dg-warning "shadows a parameter" } */
+  }
+}
+
+void foo3 ()
+{
+  int local;                   /* { dg-warning "shadowed declaration" } */
+  {
+    int local;                 /* { dg-warning "shadows a previous local" } */
+  }
+}