diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7aa661884d8..7d258102264 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2010-07-02 Le-Chun Wu + + PR/44128 + * doc/invoke.texi: Update documentation of -Wshadow. + 2010-07-02 Daniel Jacobowitz Julian Brown Sandra Loosemore diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 33aee8a96b0..e7a9e858f85 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2010-07-02 Le-Chun Wu + + PR/44128 + * name-lookup.c (pushdecl_maybe_friend): Warn when a local decl + (variable or type) shadows another type. + 2010-07-02 Jakub Jelinek PR c++/44780 diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 67131190305..153bdfd0ed5 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1017,10 +1017,22 @@ pushdecl_maybe_friend (tree x, bool is_friend) /* Inline decls shadow nothing. */ && !DECL_FROM_INLINE (x) && (TREE_CODE (oldlocal) == PARM_DECL - || TREE_CODE (oldlocal) == VAR_DECL) - /* Don't check the `this' parameter. */ - && !DECL_ARTIFICIAL (oldlocal) - && !DECL_ARTIFICIAL (x)) + || TREE_CODE (oldlocal) == VAR_DECL + /* If the old decl is a type decl, only warn if the + old decl is an explicit typedef or if both the old + and new decls are type decls. */ + || (TREE_CODE (oldlocal) == TYPE_DECL + && (!DECL_ARTIFICIAL (oldlocal) + || TREE_CODE (x) == TYPE_DECL))) + /* Don't check the `this' parameter or internally generated + vars unless it's an implicit typedef (see + create_implicit_typedef in decl.c). */ + && (!DECL_ARTIFICIAL (oldlocal) + || DECL_IMPLICIT_TYPEDEF_P (oldlocal)) + /* Don't check for internally generated vars unless + it's an implicit typedef (see create_implicit_typedef + in decl.c). */ + && (!DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x))) { bool nowarn = false; @@ -1081,10 +1093,12 @@ pushdecl_maybe_friend (tree x, bool is_friend) /* Maybe warn if shadowing something else. */ 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)) + /* No shadow warnings for internally generated vars unless + it's an implicit typedef (see create_implicit_typedef + in decl.c). */ + && (! DECL_ARTIFICIAL (x) || DECL_IMPLICIT_TYPEDEF_P (x)) + /* No shadow warnings for vars made for inlining. */ + && ! DECL_FROM_INLINE (x)) { tree member; @@ -1103,7 +1117,13 @@ pushdecl_maybe_friend (tree x, bool is_friend) x); } else if (oldglobal != NULL_TREE - && TREE_CODE (oldglobal) == VAR_DECL) + && (TREE_CODE (oldglobal) == VAR_DECL + /* If the old decl is a type decl, only warn if the + old decl is an explicit typedef or if both the + old and new decls are type decls. */ + || (TREE_CODE (oldglobal) == TYPE_DECL + && (!DECL_ARTIFICIAL (oldglobal) + || TREE_CODE (x) == TYPE_DECL)))) /* XXX shadow warnings in outer-more namespaces */ { warning_at (input_location, OPT_Wshadow, diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 458dc79d152..01066458212 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3859,8 +3859,10 @@ Do not warn whenever an @samp{#else} or an @samp{#endif} are followed by text. @item -Wshadow @opindex Wshadow @opindex Wno-shadow -Warn whenever a local variable shadows another local variable, parameter or -global variable or whenever a built-in function is shadowed. +Warn whenever a local variable or type declaration shadows another variable, +parameter, type, or class member (in C++), or whenever a built-in function +is shadowed. Note that in C++, the compiler will not warn if a local variable +shadows a struct/class/enum, but will warn if it shadows an explicit typedef. @item -Wlarger-than=@var{len} @opindex Wlarger-than=@var{len} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d4ee6d8cbee..ea3e85660cb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-07-02 Le-Chun Wu + + PR/44128 + * g++.dg/warn/Wshadow-7.C: New test. + 2010-07-02 Daniel Jacobowitz Julian Brown Sandra Loosemore diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-7.C b/gcc/testsuite/g++.dg/warn/Wshadow-7.C new file mode 100644 index 00000000000..5de952ee790 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wshadow-7.C @@ -0,0 +1,37 @@ +// PR c++/44128 +// { dg-options "-Wshadow" } + +typedef long My_ssize_t; // { dg-warning "shadowed declaration" } +typedef int Foo; // { dg-warning "shadowed declaration" } +struct Bar1 { // { dg-bogus "shadowed declaration" } + int a; +}; +struct Bar2 { // { dg-warning "shadowed declaration" } + int a; +}; + +void func() { + typedef int My_ssize_t; // { dg-warning "shadows a global" } + typedef char My_Num; // { dg-warning "shadowed declaration" } + { + typedef short My_Num; // { dg-warning "shadows a previous local" } + } + int Foo; // { dg-warning "shadows a global" } + float Bar1; // { dg-bogus "shadows a global" } + struct Bar2 { // { dg-warning "shadows a global" } + int a; + }; + struct Bar3 { // { dg-warning "shadowed declaration" } + int a; + }; + struct Bar4 { // { dg-bogus "shadowed declaration" } + int a; + }; + { + struct Bar3 { // { dg-warning "shadows a previous local" } + int a; + }; + char Bar4; // { dg-bogus "shadows a previous local" } + int My_Num; // { dg-warning "shadows a previous local" } + } +}