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>
* 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 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);
}
}

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>
* 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
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++);
}