From: Neil Booth Date: Wed, 5 Dec 2001 23:20:00 +0000 (+0000) Subject: c-common.c (shadow_warning): New function, moved from cp/decl.c. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=26f943fd3600236b05ab91a36f7ee8f1043c07af;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a813ffcc56e..941d79568fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2001-12-05 Neil Booth + + * 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 * config/alpha/vms.h (SIZE_TYPE, PTRDIFF_TYPE): Remove, were disabled. diff --git a/gcc/c-common.c b/gcc/c-common.c index f5fc0d348f5..29bb05948c1 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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"); +} + diff --git a/gcc/c-common.h b/gcc/c-common.h index 4ab415c1f1e..33835f653db 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -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 diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 5471f6b268e..fb1d8e8653d 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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b01f868c7a8..a0a3f49fb14 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2001-12-05 Neil Booth + + * decl.c: Include c-common.h. + (shadow_warning): Move to c-common.c. + Wed Dec 5 17:00:49 2001 Richard Kenner * decl.c (duplicate_decls): Don't copy DECL_NO_CHECK_MEMORY_USAGE. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3916610a310..2df8b229182 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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). diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 95b055cb7a1..3e9d657510e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-12-05 Neil Booth + + * gcc.dg/Wshadow-1.c: New test. + 2001-12-05 Jakub Jelinek * 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 index 00000000000..63808aa9c89 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wshadow-1.c @@ -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" } */ + } +}