decl.c (shadow_warning): New function.

* 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.

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

From-SVN: r46852
This commit is contained in:
Neil Booth 2001-11-08 19:04:43 +00:00 committed by Neil Booth
parent 86724f7f86
commit 8ac9ea616e
5 changed files with 104 additions and 30 deletions

View 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> 2001-11-08 Richard Henderson <rth@redhat.com>
* config/fp-bit.h (usi_to_float): Define for US_SOFTWARE_GOFAST * config/fp-bit.h (usi_to_float): Define for US_SOFTWARE_GOFAST

View 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 tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
static void store_parm_decls PARAMS ((tree)); static void store_parm_decls PARAMS ((tree));
static int cp_missing_noreturn_ok_p 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) #if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PARAMS ((void)); static void indent PARAMS ((void));
@ -3788,6 +3789,20 @@ duplicate_decls (newdecl, olddecl)
return 1; 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. /* Record a decl-node X as belonging to the current lexical scope.
Check for errors (such as an incompatible declaration for the same Check for errors (such as an incompatible declaration for the same
name already seen in the same scope). name already seen in the same scope).
@ -4173,47 +4188,53 @@ pushdecl (x)
if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x) if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
/* Inline decls shadow nothing. */ /* Inline decls shadow nothing. */
&& !DECL_FROM_INLINE (x) && !DECL_FROM_INLINE (x)
&& TREE_CODE (oldlocal) == PARM_DECL && 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)
{ {
/* Go to where the parms should be and see if we bool err = false;
find them there. */
struct binding_level *b = current_binding_level->level_chain;
if (cleanup_label) /* Don't complain if it's from an enclosing function. */
b = b->level_chain; 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 (cleanup_label)
if (b->parm_flag == 1) b = b->level_chain;
cp_error ("declaration of `%#D' shadows a parameter", name);
/* 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. */ /* Maybe warn if shadowing something else. */
if (warn_shadow && !DECL_EXTERNAL (x) else if (warn_shadow && !DECL_EXTERNAL (x)
/* Inline decls shadow nothing. */
&& !DECL_FROM_INLINE (x)
/* No shadow warnings for internally generated vars. */ /* No shadow warnings for internally generated vars. */
&& ! DECL_ARTIFICIAL (x) && ! DECL_ARTIFICIAL (x)
/* No shadow warnings for vars made for inlining. */ /* No shadow warnings for vars made for inlining. */
&& ! DECL_FROM_INLINE (x)) && ! DECL_FROM_INLINE (x))
{ {
if (oldlocal != NULL_TREE && TREE_CODE (oldlocal) == PARM_DECL) if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE
warning ("declaration of `%s' shadows a parameter",
IDENTIFIER_POINTER (name));
else if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE
&& current_class_ptr && current_class_ptr
&& !TREE_STATIC (name)) && !TREE_STATIC (name))
warning ("declaration of `%s' shadows a member of `this'", cp_warning ("declaration of `%s' shadows a member of `this'",
IDENTIFIER_POINTER (name)); IDENTIFIER_POINTER (name));
else if (oldlocal != NULL_TREE) else if (oldlocal != NULL_TREE
warning ("declaration of `%s' shadows previous local", && TREE_CODE (oldlocal) == VAR_DECL)
IDENTIFIER_POINTER (name)); shadow_warning ("a previous local", name, oldlocal);
else if (oldglobal != NULL_TREE) else if (oldglobal != NULL_TREE
&& TREE_CODE (oldglobal) == VAR_DECL)
/* XXX shadow warnings in outer-more namespaces */ /* XXX shadow warnings in outer-more namespaces */
warning ("declaration of `%s' shadows global declaration", shadow_warning ("a global declaration", name, oldglobal);
IDENTIFIER_POINTER (name));
} }
} }

View 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> 2001-11-06 Joseph S. Myers <jsm28@cam.ac.uk>
* gcc.dg/c90-array-lval-1.c, gcc.dg/c90-array-lval-2.c, * gcc.dg/c90-array-lval-1.c, gcc.dg/c90-array-lval-2.c,

View File

@ -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" }
}
}

View File

@ -1,9 +1,9 @@
// Special g++ Options: -Wshadow // Special g++ Options: -Wshadow
int int
main(int i) { main(int i) { // WARNING - shadowed decl
for(int i=1; i < 3; i++); // WARNING - shadows parm for(int i=1; i < 3; i++); // WARNING - declaration of
for(int i=1; i < 3; i++); // WARNING - shadows parm for(int i=1; i < 3; i++); // WARNING - declaration of
for(int j=1; j < 3; j++); for(int j=1; j < 3; j++);
for(int j=1; j < 3; j++); for(int j=1; j < 3; j++);
} }