On Sun, 16 Oct 2016, Jeremie Courreges-Anglas wrote:
> CVSROOT: /cvs
> Module name: src
> Changes by: [email protected] 2016/10/16 04:40:59
>
> Modified files:
> usr.sbin/rpc.bootparamd: bootparamd.c
>
> Log message:
> Rename local variable 'err' to 'error', to avoid -Wshadow conflicts with err.h
Ick. I know that newer gcc's have stopped generating shadow warning for
local variables vs global functions, such as this case. Making these
changes just because we have an old gcc is kinda annoying.
So let's fix that and make our gcc a bit more like new ones. Written
without peeking at the new ones and tested against the .c file at bottom
to verify that it doesn't fail or crash on some weird combo of shadowing.
oks?
Philip Guenther
Index: c-decl.c
===================================================================
RCS file: /data/src/openbsd/src/gnu/gcc/gcc/c-decl.c,v
retrieving revision 1.4
diff -u -p -r1.4 c-decl.c
--- c-decl.c 10 Sep 2015 10:56:35 -0000 1.4
+++ c-decl.c 16 Oct 2016 20:50:10 -0000
@@ -1946,8 +1946,19 @@ warn_if_shadowing (tree new_decl)
warning (OPT_Wshadow, "declaration of %q+D shadows a parameter",
new_decl);
else if (DECL_FILE_SCOPE_P (old_decl))
- warning (OPT_Wshadow, "declaration of %q+D shadows a global "
- "declaration", new_decl);
+ {
+ /* Don't warn about shadowing a global function unless the local
+ variable is a pointer to a function */
+ if (TREE_CODE (old_decl) == FUNCTION_DECL
+ && TREE_CODE (new_decl) != FUNCTION_DECL
+ && (TREE_CODE (new_decl) != VAR_DECL
+ || !POINTER_TYPE_P (TREE_TYPE (new_decl))
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (new_decl)))
+ != FUNCTION_TYPE))
+ break;
+ warning (OPT_Wshadow, "declaration of %q+D shadows a global "
+ "declaration", new_decl);
+ }
else if (TREE_CODE (old_decl) == FUNCTION_DECL
&& DECL_BUILT_IN (old_decl))
{
------ test-shadow.c -------
int var;
void func(void);
void (*func_ptr)(void) = func;
enum { ENUM };
typedef int type;
void
test_var(int var_arg, void (*func_ptr_arg)(void))
{
int var;
int func;
int func_ptr;
int ENUM;
int type;
{
int var_arg;
int func_ptr_arg;
}
}
void
test_func_ptr(int var_arg, void (*func_ptr_arg)(void))
{
void (*var)(void);
void (*func)(void);
void (*func_ptr)(void);
void (*ENUM)(void);
void (*type)(void);
{
void (*var_arg)(void);
void (*func_ptr_arg)(void);
}
}
void
test_int_ptr(int var_arg, void (*func_ptr_arg)(void))
{
int *var;
int *func;
int *func_ptr;
int *ENUM;
int *type;
{
int *var_arg;
int *func_ptr_arg;
}
}
void
test_enum(int var_arg, void (*func_ptr_arg)(void))
{
enum { var };
enum { func };
enum { func_ptr };
enum { ENUM };
enum { type };
{
enum { var_arg };
enum { func_ptr_arg };
}
}
void
test_type(int var_arg, void (*func_ptr_arg)(void))
{
typedef int var;
typedef int func;
typedef int func_ptr;
typedef int ENUM;
typedef int type;
{
typedef int var_arg;
typedef int func_ptr_arg;
}
}
void
test_var_param(
int var,
int func,
int func_ptr,
int ENUM,
int type)
{
}
void
test_func_ptr_param(
void (*var)(void),
void (*func)(void),
void (*func_ptr)(void),
void (*ENUM)(void),
void (*type)(void))
{
}