diff options
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 56 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wshadow-4.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wshadow-5.C | 33 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wshadow-6.C | 39 |
6 files changed, 129 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cd8dfd2..d21c713 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2010-05-14 Shujing Zhao <pearly.zhao@oracle.com> + + PR c++/30566 + * name-lookup.c (pushdecl_maybe_friend): Avoid the warnings about + shadowing the outer parameter or variables by the declaration of + nested function in nested structure or class. Warn the shadowing by + the declaration of nested lambda expression. + 2010-05-13 Jason Merrill <jason@redhat.com> * typeck.c (cp_build_array_ref): Factor out from... diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 88a3e39..405bf16 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1016,15 +1016,18 @@ pushdecl_maybe_friend (tree x, bool is_friend) else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x) /* Inline decls shadow nothing. */ && !DECL_FROM_INLINE (x) - && TREE_CODE (oldlocal) == PARM_DECL + && (TREE_CODE (oldlocal) == PARM_DECL + || TREE_CODE (oldlocal) == VAR_DECL) /* Don't check the `this' parameter. */ - && !DECL_ARTIFICIAL (oldlocal)) + && !DECL_ARTIFICIAL (oldlocal) + && !DECL_ARTIFICIAL (x)) { - bool err = false; + bool nowarn = false; /* Don't complain if it's from an enclosing function. */ if (DECL_CONTEXT (oldlocal) == current_function_decl - && TREE_CODE (x) != PARM_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. */ @@ -1038,16 +1041,41 @@ pushdecl_maybe_friend (tree x, bool is_friend) if (b->kind == sk_function_parms) { error ("declaration of %q#D shadows a parameter", x); - err = true; + nowarn = true; } } - if (warn_shadow && !err) + /* The local structure or class can't use parameters of + the containing function anyway. */ + if (DECL_CONTEXT (oldlocal) != current_function_decl) { - warning_at (input_location, OPT_Wshadow, - "declaration of %q#D shadows a parameter", x); - warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow, - "shadowed declaration is here"); + cxx_scope *scope = current_binding_level; + tree context = DECL_CONTEXT (oldlocal); + for (; scope; scope = scope->level_chain) + { + if (scope->kind == sk_function_parms + && scope->this_entity == context) + break; + if (scope->kind == sk_class + && !LAMBDA_TYPE_P (scope->this_entity)) + { + nowarn = true; + break; + } + } + } + + if (warn_shadow && !nowarn) + { + if (TREE_CODE (oldlocal) == PARM_DECL) + warning_at (input_location, OPT_Wshadow, + "declaration of %q#D shadows a parameter", x); + else + warning_at (input_location, OPT_Wshadow, + "declaration of %qD shadows a previous local", + x); + warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow, + "shadowed declaration is here"); } } @@ -1074,14 +1102,6 @@ pushdecl_maybe_friend (tree x, bool is_friend) warning (OPT_Wshadow, "declaration of %qD shadows a member of 'this'", x); } - else if (oldlocal != NULL_TREE - && TREE_CODE (oldlocal) == VAR_DECL) - { - warning_at (input_location, OPT_Wshadow, - "declaration of %qD shadows a previous local", x); - warning_at (DECL_SOURCE_LOCATION (oldlocal), OPT_Wshadow, - "shadowed declaration is here"); - } else if (oldglobal != NULL_TREE && TREE_CODE (oldglobal) == VAR_DECL) /* XXX shadow warnings in outer-more namespaces */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7c50d61..6320390 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2010-05-14 Shujing Zhao <pearly.zhao@oracle.com> + + PR c++/30566 + * testsuite/g++.dg/warn/Wshadow-4.C: Adjust. + * testsuite/g++.dg/warn/Wshadow-5.C: New test. + * testsuite/g++.dg/warn/Wshadow-6.C: New test + 2010-05-13 Daniel Franke <franke.daniel@gmail.com> PR fortran/35779 diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-4.C b/gcc/testsuite/g++.dg/warn/Wshadow-4.C index 2238653..c033028 100644 --- a/gcc/testsuite/g++.dg/warn/Wshadow-4.C +++ b/gcc/testsuite/g++.dg/warn/Wshadow-4.C @@ -8,13 +8,13 @@ public: int GetMainURL() const; }; -int foo(int infoo) // { dg-warning "shadowed declaration" } +int foo(int infoo) // { dg-bogus "shadowed declaration" } { int outfoo( INetURLObject( infoo ).GetMainURL()); // { dg-bogus "shadows" } extern void f(int infoo); struct A { - void f(int infoo) { } // { dg-warning "shadows a parameter" } + void f(int infoo) { } // { dg-bogus "shadows a parameter" } }; return outfoo; } @@ -22,11 +22,11 @@ int foo(int infoo) // { dg-warning "shadowed declaration" } // PR c++/39763 int foo2(void) { - int infoo = 0; // { dg-warning "shadowed declaration" } + int infoo = 0; // { dg-bogus "shadowed declaration" } int outfoo( INetURLObject( infoo ).GetMainURL()); // { dg-bogus "shadows" } struct A { - void f(int infoo) { } // { dg-warning "shadows a previous local" } + void f(int infoo) { } // { dg-bogus "shadows a previous local" } }; return outfoo; } diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-5.C b/gcc/testsuite/g++.dg/warn/Wshadow-5.C new file mode 100644 index 0000000..6623291 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wshadow-5.C @@ -0,0 +1,33 @@ +// Wshadows was giving warnings for nested function parameters in nested class +// or structure that we didn't want. +// { dg-do compile } +// { dg-options "-Wshadow" } + +// PR c++/41825 +int f (int n) +{ + int bar (int n) { return n++; } // { dg-error "a function-definition is not allowed here" } + return bar (n); // { dg-error "was not declared in this scope" } +} + +int g (int i) +{ + struct { + int bar (int i) { return i++; } // { dg-bogus "shadows" } + } s; + + return s.bar (i); +} + +// PR c++/30566 +void h( int x ) +{ + class InnerClass + { + public: + static int g( int x ) // { dg-bogus "shadows" } + { + // empty + } + }; +} diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-6.C b/gcc/testsuite/g++.dg/warn/Wshadow-6.C new file mode 100644 index 0000000..9b13e3a --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wshadow-6.C @@ -0,0 +1,39 @@ +// Test the declaration of nested lambda function shadows +// a parameter or previous local. +// { dg-do compile } +// { dg-options "-std=c++0x -Wshadow" } + +struct S {}; +int f1(int x) // { dg-warning "shadowed declaration" } +{ + int t = 0; + int m = 0; // { dg-warning "shadowed declaration" } + [&t] (int x) { // { dg-warning "shadows a parameter" } + int m = 1; // { dg-warning "shadows a previous local" } + t = t + x + m; + }; + return t; +} + +void f2(struct S i, int j) { + struct A { + struct S x; + void g(struct S i) { // { dg-warning "shadowed declaration" } + struct S x; // { dg-warning "shadows a member of" } + struct S y; // { dg-warning "shadowed declaration" } + int t; + [&t](struct S i){ // { dg-warning "shadows a parameter" } + int j = 1; // { dg-bogus "shadows" } + struct S y; // { dg-warning "shadows a previous local" } + t = j; + }; + } + }; +} + +void f3(int i) { + [=]{ + int j = i; + int i; // { dg-warning "shadows a member of" } + }; +} |