aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.demon.co.uk>2001-11-08 19:04:43 +0000
committerNeil Booth <neil@gcc.gnu.org>2001-11-08 19:04:43 +0000
commit8ac9ea616e01991beb4164c1a44647763d33302c (patch)
tree76fd6ca76e5f6ba17b56e70c9283886caa7a0d95 /gcc
parent86724f7f86713c04e2e2be9e866032b12ff64a61 (diff)
downloadgcc-8ac9ea616e01991beb4164c1a44647763d33302c.zip
gcc-8ac9ea616e01991beb4164c1a44647763d33302c.tar.gz
gcc-8ac9ea616e01991beb4164c1a44647763d33302c.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cp/decl.c75
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/warn/Wshadow-1.C42
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/for3.C6
5 files changed, 104 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d442d11..b410b51 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1b3fc9e..a210a7b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d11a53d..cd31ce7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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,
diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-1.C b/gcc/testsuite/g++.dg/warn/Wshadow-1.C
new file mode 100644
index 0000000..b7d95e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wshadow-1.C
@@ -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" }
+ }
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/for3.C b/gcc/testsuite/g++.old-deja/g++.mike/for3.C
index a8276a4..7e88d7e 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/for3.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/for3.C
@@ -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++);
}