aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.demon.co.uk>2001-12-05 23:20:00 +0000
committerNeil Booth <neil@gcc.gnu.org>2001-12-05 23:20:00 +0000
commit26f943fd3600236b05ab91a36f7ee8f1043c07af (patch)
treee2ef9f427adfe62b09b758c20b2ffdb1802526ba /gcc/c-decl.c
parent8ca8f9a70b751319f7281564aa0ab0e93b3ef6e2 (diff)
downloadgcc-26f943fd3600236b05ab91a36f7ee8f1043c07af.zip
gcc-26f943fd3600236b05ab91a36f7ee8f1043c07af.tar.gz
gcc-26f943fd3600236b05ab91a36f7ee8f1043c07af.tar.bz2
c-common.c (shadow_warning): New function, moved from cp/decl.c.
* 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
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c117
1 files changed, 72 insertions, 45 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 5471f6b..fb1d8e8 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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));
/* 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;
}
/* Finish up a function declaration and compile that function