Commit 8ac9ea61 by Neil Booth Committed by Neil Booth

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
parent 86724f7f
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
......
...@@ -147,6 +147,7 @@ static tree push_cp_library_fn PARAMS ((enum tree_code, tree)); ...@@ -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) ...@@ -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,13 +4188,16 @@ pushdecl (x) ...@@ -4173,13 +4188,16 @@ 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)
{
bool err = false;
/* Don't complain if it's from an enclosing function. */ /* Don't complain if it's from an enclosing function. */
&& DECL_CONTEXT (oldlocal) == current_function_decl if (DECL_CONTEXT (oldlocal) == current_function_decl
&& TREE_CODE (x) != PARM_DECL) && TREE_CODE (x) != PARM_DECL)
{ {
/* Go to where the parms should be and see if we /* Go to where the parms should be and see if we find
find them there. */ them there. */
struct binding_level *b = current_binding_level->level_chain; struct binding_level *b = current_binding_level->level_chain;
if (cleanup_label) if (cleanup_label)
...@@ -4187,33 +4205,36 @@ pushdecl (x) ...@@ -4187,33 +4205,36 @@ pushdecl (x)
/* ARM $8.3 */ /* ARM $8.3 */
if (b->parm_flag == 1) if (b->parm_flag == 1)
cp_error ("declaration of `%#D' shadows a parameter", name); {
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));
} }
} }
......
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,
......
/* 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" }
}
}
// 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++);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment