This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PR 40989: Fix Wimplicit
- From: Manuel López-Ibáñez <lopezibanez at gmail dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>, "fortran at gcc dot gnu dot org List" <fortran at gcc dot gnu dot org>
- Date: Sat, 1 May 2010 14:47:36 +0200
- Subject: PR 40989: Fix Wimplicit
The problem here is that group options (options that enable other
options) are not handled correctly when enabled by -Werror=. The
following patch fixes this issue for Wimplicit but also adds the
infrastructure to fix it for all other options. When
enabling/disabling an option, we should always use the new
process_option function.
In the future, we should be able to generate the calls to
process_option automatically from the .opt files.
Bootstrapped and regression tested on x86_64-linux-gnu. OK?
2010-05-01 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR 40989
* opts.c (common_handle_option): Add argument kind.
(handle_option): Factor out code to...
(process_option): ... here. New.
(set_option): Use option index instead of option pointer. Classify
diagnostics correctly.
(enable_warning_as_error): Call process_option.
* opts.h (set_option): Update declaration.
(process_option): Declare.
* langhooks.h (struct lang_hooks): Add argument kind to
handle_option.
* c.opt (Wimplicit,Wimplicit-int): Initialize to -1.
* c-opts.c (set_Wimplicit): Delete.
(lang_mask): New static constant.
(c_common_handle_option): Add argument kind. Use process_option
instead of set_Wimplicit.
(c_common_post_options): warn_implicit and warn_implicit_int
are disabled by default.
* c-common.c (warn_implicit): Do not define here.
* c-common.h (warn_implicit): Do not declare here.
(c_common_handle_option): Update declaration.
* lto-opts.c (lto_reissue_options): Update call to set_option.
java/
* lang.c (java_handle_option): Add argument kind.
fortran/
* options.c (gfc_handle_option): Add argument kind.
* gfortran.h (gfc_handle_option): Update declaration.
testsuite/
* gcc.dg/pr40989.c: New.
Index: gcc/java/lang.c
===================================================================
--- gcc/java/lang.c (revision 158909)
+++ gcc/java/lang.c (working copy)
@@ -50,11 +50,11 @@ The Free Software Foundation is independ
static bool java_init (void);
static void java_finish (void);
static unsigned int java_init_options (unsigned int, const char **);
static bool java_post_options (const char **);
-static int java_handle_option (size_t scode, const char *arg, int value);
+static int java_handle_option (size_t scode, const char *arg, int value, int kind);
static void put_decl_string (const char *, int);
static void put_decl_node (tree, int);
static void java_print_error_function (diagnostic_context *, const char *,
diagnostic_info *);
static int merge_init_test_initialization (void * *, void *);
@@ -173,11 +173,12 @@ struct lang_hooks lang_hooks = LANG_HOOK
/*
* process java-specific compiler command-line options
* return 0, but do not complain if the option is not recognized.
*/
static int
-java_handle_option (size_t scode, const char *arg, int value)
+java_handle_option (size_t scode, const char *arg, int value,
+ int kind ATTRIBUTE_UNUSED)
{
enum opt_code code = (enum opt_code) scode;
switch (code)
{
Index: gcc/testsuite/gcc.dg/pr40989.c
===================================================================
--- gcc/testsuite/gcc.dg/pr40989.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr40989.c (revision 0)
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Werror=implicit" } */
+int main() {
+ return pippo(); /* { dg-error "" } */
+}
+/* { dg-message "warnings being treated as errors" "" { target *-*-* } 0 } */
Index: gcc/opts.c
===================================================================
--- gcc/opts.c (revision 158909)
+++ gcc/opts.c (working copy)
@@ -370,11 +370,11 @@ bool flag_warn_unused_result = false;
/* Input file names. */
const char **in_fnames;
unsigned num_in_fnames;
static int common_handle_option (size_t scode, const char *arg, int value,
- unsigned int lang_mask);
+ unsigned int lang_mask, int kind);
static void handle_param (const char *);
static unsigned int handle_option (const char **argv, unsigned int lang_mask);
static char *write_langs (unsigned int lang_mask);
static void complain_wrong_lang (const char *, const struct cl_option *,
unsigned int lang_mask);
@@ -483,10 +483,51 @@ void print_ignored_options (void)
}
input_location = saved_loc;
}
+
+/* Process an option OPTION, with option index OPT_INDEX, and argument
+ ARG, for the language indicated by LANG_MASK. VALUE is true,
+ unless no- form of an -f or -W option was given. KIND is the
+ diagnostic_t if this is a diagnostics option, DK_UNSPECIFIED
+ otherwise. Returns false if the switch was invalid. */
+bool
+process_option (int opt_index, int value, const char *arg,
+ unsigned int lang_mask, int kind)
+{
+ const struct cl_option *option = &cl_options[opt_index];
+
+ if (option->flag_var)
+ set_option (opt_index, value, arg, kind);
+
+ if (option->flags & lang_mask)
+ {
+ if (lang_hooks.handle_option (opt_index, arg, value, kind) == 0)
+ return false;
+ else
+ lto_register_user_option (opt_index, arg, value, lang_mask);
+ }
+
+ if (option->flags & CL_COMMON)
+ {
+ if (common_handle_option (opt_index, arg, value, lang_mask, kind) == 0)
+ return false;
+ else
+ lto_register_user_option (opt_index, arg, value, CL_COMMON);
+ }
+
+ if (option->flags & CL_TARGET)
+ {
+ if (!targetm.handle_option (opt_index, arg, value))
+ return false;
+ else
+ lto_register_user_option (opt_index, arg, value, CL_TARGET);
+ }
+ return true;
+}
+
/* Handle the switch beginning at ARGV for the language indicated by
LANG_MASK. Returns the number of switches consumed. */
static unsigned int
handle_option (const char **argv, unsigned int lang_mask)
{
@@ -607,36 +648,12 @@ handle_option (const char **argv, unsign
option->opt_text);
goto done;
}
}
- if (option->flag_var)
- set_option (option, value, arg);
-
- if (option->flags & lang_mask)
- {
- if (lang_hooks.handle_option (opt_index, arg, value) == 0)
- result = 0;
- else
- lto_register_user_option (opt_index, arg, value, lang_mask);
- }
-
- if (result && (option->flags & CL_COMMON))
- {
- if (common_handle_option (opt_index, arg, value, lang_mask) == 0)
- result = 0;
- else
- lto_register_user_option (opt_index, arg, value, CL_COMMON);
- }
-
- if (result && (option->flags & CL_TARGET))
- {
- if (!targetm.handle_option (opt_index, arg, value))
- result = 0;
- else
- lto_register_user_option (opt_index, arg, value, CL_TARGET);
- }
+ if (!process_option (opt_index, value, arg, lang_mask, DK_UNSPECIFIED))
+ result = 0;
done:
if (dup)
free (dup);
return result;
@@ -1462,11 +1479,11 @@ print_specific_help (unsigned int includ
extra handling need to be listed here; if you simply want
VALUE assigned to a variable, it happens automatically. */
static int
common_handle_option (size_t scode, const char *arg, int value,
- unsigned int lang_mask)
+ unsigned int lang_mask, int kind ATTRIBUTE_UNUSED)
{
static bool verbose = false;
enum opt_code code = (enum opt_code) scode;
switch (code)
@@ -2371,12 +2388,14 @@ get_option_state (int option, struct cl_
}
/* Set *OPTION according to VALUE and ARG. */
void
-set_option (const struct cl_option *option, int value, const char *arg)
+set_option (int opt_index, int value, const char *arg, int kind)
{
+ const struct cl_option *option = &cl_options[opt_index];
+
if (!option->flag_var)
return;
switch (option->var_type)
{
@@ -2402,10 +2421,13 @@ set_option (const struct cl_option *opti
case CLVC_STRING:
*(const char **) option->flag_var = arg;
break;
}
+
+ if ((diagnostic_t)kind != DK_UNSPECIFIED)
+ diagnostic_classify_diagnostic (global_dc, opt_index, (diagnostic_t)kind);
}
/* Callback function, called when -Werror= enables a warning. */
@@ -2445,12 +2467,12 @@ enable_warning_as_error (const char *arg
if (kind == DK_ERROR)
{
const struct cl_option * const option = cl_options + option_index;
/* -Werror=foo implies -Wfoo. */
- if (option->var_type == CLVC_BOOLEAN && option->flag_var)
- *(int *) option->flag_var = 1;
+ if (option->var_type == CLVC_BOOLEAN)
+ process_option (option_index, value, arg, lang_mask, (int)kind);
if (warning_as_error_callback)
warning_as_error_callback (option_index);
}
}
Index: gcc/opts.h
===================================================================
--- gcc/opts.h (revision 158909)
+++ gcc/opts.h (working copy)
@@ -101,12 +101,13 @@ extern unsigned num_in_fnames;
size_t find_opt (const char *input, int lang_mask);
extern void prune_options (int *argcp, char ***argvp);
extern void decode_options (unsigned int argc, const char **argv);
extern int option_enabled (int opt_idx);
extern bool get_option_state (int, struct cl_option_state *);
-extern void set_option (const struct cl_option *, int, const char *);
-
+extern void set_option (int opt_index, int value, const char *arg, int);
+bool process_option (int opt_index, int value, const char *arg,
+ unsigned int lang_mask, int kind);
extern void register_warning_as_error_callback (void (*callback) (int));
extern void enable_warning_as_error (const char *arg, int value,
unsigned int lang_mask);
extern void print_ignored_options (void);
#endif
Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h (revision 158909)
+++ gcc/fortran/gfortran.h (working copy)
@@ -2321,11 +2321,11 @@ void gfc_done_2 (void);
int get_c_kind (const char *, CInteropKind_t *);
/* options.c */
unsigned int gfc_init_options (unsigned int, const char **);
-int gfc_handle_option (size_t, const char *, int);
+int gfc_handle_option (size_t, const char *, int, int);
bool gfc_post_options (const char **);
/* f95-lang.c */
void gfc_maybe_initialize_eh (void);
Index: gcc/fortran/options.c
===================================================================
--- gcc/fortran/options.c (revision 158909)
+++ gcc/fortran/options.c (working copy)
@@ -530,11 +530,12 @@ gfc_handle_runtime_check_option (const c
/* Handle command-line options. Returns 0 if unrecognized, 1 if
recognized and handled. */
int
-gfc_handle_option (size_t scode, const char *arg, int value)
+gfc_handle_option (size_t scode, const char *arg, int value,
+ int kind ATTRIBUTE_UNUSED)
{
int result = 1;
enum opt_code code = (enum opt_code) scode;
/* Ignore file names. */
Index: gcc/langhooks.h
===================================================================
--- gcc/langhooks.h (revision 158909)
+++ gcc/langhooks.h (working copy)
@@ -281,11 +281,11 @@ struct lang_hooks
was in fact supplied. For -f and -W switches, VALUE is 1 or 0
for the positive and negative forms respectively.
Return 1 if the switch is valid, 0 if invalid, and -1 if it's
valid and should not be treated as language-independent too. */
- int (*handle_option) (size_t code, const char *arg, int value);
+ int (*handle_option) (size_t code, const char *arg, int value, int kind);
/* Return false to use the default complaint about a missing
argument, otherwise output a complaint and return true. */
bool (*missing_argument) (const char *opt, size_t code);
Index: gcc/c.opt
===================================================================
--- gcc/c.opt (revision 158909)
+++ gcc/c.opt (working copy)
@@ -261,18 +261,19 @@ Warn whenever type qualifiers are ignore
Winit-self
C ObjC C++ ObjC++ Var(warn_init_self) Warning
Warn about variables which are initialized to themselves
Wimplicit
-C ObjC C++ ObjC++ Warning
+C ObjC C++ ObjC++ Var(warn_implicit) Init(-1) Warning
+Warn about implicit declarations
Wimplicit-function-declaration
C ObjC Var(warn_implicit_function_declaration) Init(-1) Warning
Warn about implicit function declarations
Wimplicit-int
-C ObjC Var(warn_implicit_int) Warning
+C ObjC Var(warn_implicit_int) Init(-1) Warning
Warn when a declaration does not specify a type
Wimport
C ObjC C++ ObjC++ Undocumented
Index: gcc/c-opts.c
===================================================================
--- gcc/c-opts.c (revision 158909)
+++ gcc/c-opts.c (working copy)
@@ -104,11 +104,10 @@ static bool warn_variadic_macros = true;
static size_t deferred_count;
/* Number of deferred options scanned for -include. */
static size_t include_cursor;
-static void set_Wimplicit (int);
static void handle_OPT_d (const char *);
static void set_std_cxx98 (int);
static void set_std_cxx0x (int);
static void set_std_c89 (int, int);
static void set_std_c99 (int);
@@ -133,10 +132,13 @@ static struct deferred_opt
{
enum opt_code code;
const char *arg;
} *deferred_opts;
+
+static const unsigned int lang_mask = (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX);
+
/* Complain that switch CODE expects an argument but none was
provided. OPT was the command-line option. Return FALSE to get
the default message in opts.c, TRUE if we provide a specialized
one. */
bool
@@ -347,11 +349,12 @@ c_common_init_options (unsigned int argc
/* Handle switch SCODE with argument ARG. VALUE is true, unless no-
form of an -f or -W option was given. Returns 0 if the switch was
invalid, a negative number to prevent language-independent
processing in toplev.c (a hack necessary for the short-term). */
int
-c_common_handle_option (size_t scode, const char *arg, int value)
+c_common_handle_option (size_t scode, const char *arg, int value,
+ int kind)
{
const struct cl_option *option = &cl_options[scode];
enum opt_code code = (enum opt_code) scode;
int result = 1;
@@ -360,11 +363,11 @@ c_common_handle_option (size_t scode, co
bool preprocessing_asm_p = (cpp_get_options (parse_in)->lang == CLK_ASM);
switch (code)
{
default:
- if (cl_options[code].flags & (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX))
+ if (cl_options[code].flags & lang_mask)
{
if ((option->flags & CL_TARGET)
&& ! targetcm.handle_c_option (scode, arg, value))
result = 0;
break;
@@ -469,11 +472,11 @@ c_common_handle_option (size_t scode, co
break;
case OPT_Wall:
warn_unused = value;
set_Wformat (value);
- set_Wimplicit (value);
+ process_option (OPT_Wimplicit, value, NULL, lang_mask, kind);
warn_char_subscripts = value;
warn_missing_braces = value;
warn_parentheses = value;
warn_return_type = value;
warn_sequence_point = value; /* Was C only. */
@@ -567,11 +570,15 @@ c_common_handle_option (size_t scode, co
case OPT_Wformat_:
set_Wformat (atoi (arg));
break;
case OPT_Wimplicit:
- set_Wimplicit (value);
+ gcc_assert (value == 0 || value == 1);
+ if (warn_implicit_int == -1)
+ process_option (OPT_Wimplicit_int, value, NULL, lang_mask, kind);
+ if (warn_implicit_function_declaration == -1)
+ process_option (OPT_Wimplicit_function_declaration, value, NULL, lang_mask, kind);
break;
case OPT_Wimport:
/* Silently ignore for now. */
break;
@@ -1244,10 +1251,16 @@ c_common_post_options (const char **pfil
"-Wformat-contains-nul ignored without -Wformat");
warning (OPT_Wformat_security,
"-Wformat-security ignored without -Wformat");
}
+ if (warn_implicit == -1)
+ warn_implicit = 0;
+
+ if (warn_implicit_int == -1)
+ warn_implicit_int = 0;
+
/* -Wimplicit-function-declaration is enabled by default for C99. */
if (warn_implicit_function_declaration == -1)
warn_implicit_function_declaration = flag_isoc99;
/* If we're allowing C++0x constructs, don't warn about C++0x
@@ -1764,19 +1777,10 @@ set_std_cxx0x (int iso)
flag_no_nonansi_builtin = iso;
flag_iso = iso;
cxx_dialect = cxx0x;
}
-/* Handle setting implicit to ON. */
-static void
-set_Wimplicit (int on)
-{
- warn_implicit = on;
- warn_implicit_int = on;
- warn_implicit_function_declaration = on;
-}
-
/* Args to -d specify what to dump. Silently ignore
unrecognized options; they may be aimed at toplev.c. */
static void
handle_OPT_d (const char *arg)
{
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c (revision 158909)
+++ gcc/c-common.c (working copy)
@@ -426,14 +426,10 @@ int flag_threadsafe_statics = 1;
/* Nonzero if we want to pretty-print template specializations as the
template signature followed by the arguments. */
int flag_pretty_templates = 1;
-/* Nonzero means warn about implicit declarations. */
-
-int warn_implicit = 1;
-
/* Maximum template instantiation depth. This limit exists to limit the
time it takes to notice infinite template instantiations; the default
value of 1024 is likely to be in the next C++ standard. */
int max_tinst_depth = 1024;
Index: gcc/c-common.h
===================================================================
--- gcc/c-common.h (revision 158909)
+++ gcc/c-common.h (working copy)
@@ -748,14 +748,10 @@ extern int flag_threadsafe_statics;
/* Nonzero if we want to pretty-print template specializations as the
template signature followed by the arguments. */
extern int flag_pretty_templates;
-/* Nonzero means warn about implicit declarations. */
-
-extern int warn_implicit;
-
/* Warn about using __null (as NULL in C++) as sentinel. For code compiled
with GCC this doesn't matter as __null is guaranteed to have the right
size. */
extern int warn_strict_null_sentinel;
@@ -825,11 +821,11 @@ extern bool check_builtin_function_argum
extern void check_function_format (tree, int, tree *);
extern void set_Wformat (int);
extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
extern bool attribute_takes_identifier_p (tree);
-extern int c_common_handle_option (size_t code, const char *arg, int value);
+extern int c_common_handle_option (size_t code, const char *arg, int value, int kind);
extern bool c_common_missing_argument (const char *opt, size_t code);
extern tree c_common_type_for_mode (enum machine_mode, int);
extern tree c_common_type_for_size (unsigned int, int);
extern tree c_common_fixed_point_type_for_size (unsigned int, unsigned int,
int, int);
Index: gcc/lto-opts.c
===================================================================
--- gcc/lto-opts.c (revision 158909)
+++ gcc/lto-opts.c (working copy)
@@ -381,11 +381,11 @@ lto_reissue_options (void)
for (i = 0; VEC_iterate (opt_t, opts, i, o); i++)
{
const struct cl_option *option = &cl_options[o->code];
if (option->flag_var)
- set_option (option, o->value, o->arg);
+ set_option (o->code, o->value, o->arg, 0 /*DK_UNSPECIFIED*/);
if (o->type == CL_TARGET)
targetm.handle_option (o->code, o->arg, o->value);
else if (o->type == CL_COMMON)
gcc_assert (option->flag_var);